Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSX: 'upc_pgm_info': mach-o section specifier requires a segment and section separated by a comma #6

Closed
swatanabe opened this issue Feb 20, 2013 · 6 comments
Assignees

Comments

@swatanabe
Copy link

On Macos/Darwin, the make fails with

fatal error: error in backend: Global variable 'GCCUPCConfig' has an invalid
section specifier 'upc_pgm_info': mach-o section specifier requires a
segment and section separated by a comma.

This GCCUPCConfig variable is generated by this section of code.

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 9a55c08..895d80b 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
[...]
void CodeGenModule::Release() {

  • if (getContext().getLangOpts().UPC) {
  • llvm::SmallString<64> str;
  • str += "$GCCUPCConfig: (";
  • str += getModule().getModuleIdentifier();
  • str += ") ";
  • unsigned Threads = getContext().getLangOpts().UPCThreads;
  • if (Threads == 0) {
  •  str += "dynamicthreads";
    
  • } else {
  •  str += "staticthreads=";
    
  •  llvm::APInt(32, Threads).toStringUnsigned(str);
    
  • }
  • str += " process$";
  • llvm::GlobalVariable * conf =
  •  new llvm::GlobalVariable(getModule(), llvm::ArrayType::get(Int8Ty, str.size
    
  •                           true, llvm::GlobalValue::InternalLinkage,
    
  •                           llvm::ConstantDataArray::getString(getLLVMContext(
    
  •                           "GCCUPCConfig");
    
  • conf->setSection("upc_pgm_info");
  • AddUsedGlobal(conf);
  • }

Note the "setSection" call above.

This small test program indicates the expected section name syntax on a Mach OS based system.

static const char GCCUPCConfig[]

if MACH

attribute ((section("DATA,upc_pgm_info"))) __attribute ((used)) =

else

attribute ((section("upc_pgm_info"))) attribute ((used)) =

endif

"$GCCUPCConfig: (" BASE_FILE ") " "$";

int main(void)
{
return 0;
}

I think that the lack of the ""__DATA,upc_pgm_info" syntax might be the source of the problem, but am unsure how this might be best parametrized within the compiler. Perhaps there is already some mechanism to achieve this OS dependent behavior?

@swatanabe
Copy link
Author

I think the right way to solve this is to move this definition back into gcc-upc-lib.h. The only reason for the divergence from gupc is that I didn't completely understand how gupc handles it when I wrote this originally.

@nenadv
Copy link

nenadv commented Mar 5, 2013

I tried to push the way through this error by adding appropriate sections (__DATA) where needed. Made the following changes:

diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index f7c65dd..ebd7ed7 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -202,7 +202,11 @@ CodeGenFunction::CreateStaticVarDecl(const VarDecl &D,
if (Linkage != llvm::GlobalValue::InternalLinkage)
GV->setVisibility(CurFn->getVisibility());
if(SharedInit)
+#if MACH

  • GV->setSection("__DATA,upc_shared");
    +#else
    GV->setSection("upc_shared");
    +#endif
    return GV;
    }

diff --git a/lib/CodeGen/CGStmtUPC.cpp b/lib/CodeGen/CGStmtUPC.cpp
index 707f92b..1186d75 100644
--- a/lib/CodeGen/CGStmtUPC.cpp
+++ b/lib/CodeGen/CGStmtUPC.cpp
@@ -68,7 +68,11 @@ llvm::Constant *CodeGenModule::getUPCFenceVar() {
llvm::GlobalValue::LinkOnceODRLinkage,
llvm::ConstantInt::get(IntTy, 0),
"upc_fence_var");
+#if __MACH

  • GV->setSection("DATA,upc_shared");
    +#else
    GV->setSection("upc_shared");
    +#endif
    UPCFenceVar = GV;
    }
    return UPCFenceVar;
    diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
    index 895d80b..8bef985 100644
    --- a/lib/CodeGen/CodeGenModule.cpp
    +++ b/lib/CodeGen/CodeGenModule.cpp
    @@ -168,7 +168,11 @@ void CodeGenModule::Release() {
    true, llvm::GlobalValue::InternalLinkage,
    llvm::ConstantDataArray::getString(getLLVMContext(), str),
    "GCCUPCConfig");
    +#if __MACH
  • conf->setSection("__DATA,upc_pgm_info");
    +#else
    conf->setSection("upc_pgm_info");
    +#endif
    AddUsedGlobal(conf);
    }
    EmitDeferred();
    @@ -1655,7 +1659,11 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {

SetCommonAttributes(D, GV);
if(ASTTy.getQualifiers().hasShared())
+#if MACH

  • GV->setSection("__DATA,upc_shared");
    +#else
    GV->setSection("upc_shared");
    +#endif

// Emit the initializer function if necessary.
if (NeedsGlobalCtor || NeedsGlobalDtor)
diff --git a/runtime/libupc/CMakeLists.txt b/runtime/libupc/CMakeLists.txt
index fb93628..893d1b9 100644
--- a/runtime/libupc/CMakeLists.txt
+++ b/runtime/libupc/CMakeLists.txt
@@ -447,7 +447,7 @@ macro(add_crt_target name opts)
list(APPEND objects ${obj})
add_custom_target(${name} ALL DEPENDS ${obj})
add_custom_command(OUTPUT ${obj}

  • COMMAND ${CMAKE_C_COMPILER} -c -o ${obj} ${PROJECT_SOURCE_DIR}/upc-crtstuff.c -I${PROJECT_SOURCE_DIR}/config/default -I${
  • COMMAND ${CMAKE_C_COMPILER} -c -o ${obj} ${PROJECT_SOURCE_DIR}/upc-crtstuff.c -I${PROJECT_SOURCE_DIR}/config/darwin -I${P
    MAIN_DEPENDENCY upc-crtstuff.c
    IMPLICIT_DEPENDENCY upc-crtstuff.c
    VERBATIM)

The only change that is problematic is the one in runtime/libupc/CMakeLists.txt. I am not familiar with Cmake and don;t know how to change the include based on the system it is building on.

After this I was able to rebuild everything to the end. And did not run into the perl error. Which is interesting.

@gary-funck
Copy link

On 03/04/13 17:26:18, Nenad Vukicevic wrote:

I tried to push the way through this error by adding
appropriate sections (__DATA) where needed. Made the following changes:
[...]
After this I was able to rebuild everything to the end. And
did not run into the perl error. Which is interesting.

If you didn't 'make clean' or start from scratch, the .ld
file might've already been created, and would be empty.

Try it from scratch, with the default -j switch.

@swatanabe
Copy link
Author

Preprocessor directives aren't really the right way to handle this, as they break cross-compilation. I don't have a mac to test with, but I'll try to put something together today.

@nenadv
Copy link

nenadv commented Mar 8, 2013

It looks like we forgot one change that made some tests fail on Mac OS:

diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index ca5bf3a..d703484 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -458,7 +458,10 @@ void CodeGenModule::EmitUPCInits(const CtorList &Fns, const char *Globa
                              llvm::GlobalValue::AppendingLinkage,
                              llvm::ConstantArray::get(AT, Ctors),
                              GlobalName);
-    GV->setSection("upc_init_array");
+    if(isTargetDarwin())
+      GV->setSection("__DATA,upc_init_array");
+    else
+      GV->setSection("upc_init_array");
   }
 }

@nenadv nenadv reopened this Mar 8, 2013
@swatanabe
Copy link
Author

This patch looks fine. Please commit it.

@nenadv nenadv closed this as completed Mar 9, 2013
swatanabe pushed a commit that referenced this issue Sep 20, 2017
…ase ctor in window. Need add "complete object flag" check in eh cleanup code.

The problem only happen on window ( A MS-ABI issuer )

The nature of the problem is virtual base dtor called more than it is needed after exception throw in inheriting base class(with virtual bases) ctor.

The root problem is when throw happen, not all virtual base classes have been contructed, so not all virtual base dtors are need to call for ehcleanup.

clang has code to handle vbase initialization: basically add check for "complete object flag" before call to v-base ctor.
But that part is missing for cleanup code.

To fix this add similar code as v-base init to cleanup code, same algorithm.

1> Add new routine:
EmitDtorCompleteObjectHandler

With corresponding to EmitCtorCompleteObjectHandler

2> In the EmitDestructorCal
Call EmitDtorCompleteObjectHandler when generate ehcleanup inside ctor.

Just add check for "complete object flag" before call to v-base dtor.

Without my change:
ehcleanup: ; preds = %ctor.skip_vbases

%13 = cleanuppad within none [], !dbg !66
%14 = bitcast %struct.class_0* %this1 to i8*, !dbg !66
%15 = getelementptr inbounds i8, i8* %14, i64 8, !dbg !66
%16 = bitcast i8* %15 to %struct.class_2*, !dbg !66
call void @"\01??1class_2@@UEAA@XZ"(%struct.class_2* %16) #6 [ "funclet"(token

%13) ], !dbg !66

cleanupret from %13 unwind to caller, !dbg !66

with my change:
ehcleanup: ; preds = %ctor.skip_vbases

%13 = cleanuppad within none [], !dbg !66
%14 = bitcast %struct.class_0* %this1 to i8*, !dbg !66
%15 = getelementptr inbounds i8, i8* %14, i64 8, !dbg !66
%16 = bitcast i8* %15 to %struct.class_2*, !dbg !66
%is_complete_object4 = icmp ne i32 %is_most_derived2, 0, !dbg !66
br i1 %is_complete_object4, label %Dtor.dtor_vbase, label %Dtor.skip_vbase, !d

bg !66

Dtor.dtor_vbase: ; preds = %ehcleanup

call void @"\01??1class_2@@UEAA@XZ"(%struct.class_2* %16) #6 [ "funclet"(token

%13) ], !dbg !66

br label %Dtor.skip_vbase, !dbg !66

Dtor.skip_vbase: ; preds = %Dtor.dtor_vbase, %ehcleanup

cleanupret from %13 unwind to caller, !dbg !66

Please let me know you need more info.

Patch by Jennifer Yu.

Differential Revision: https://reviews.llvm.org/D27358



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288869 91177308-0d34-0410-b5e6-96231b3b80d8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants