Skip to content

Commit

Permalink
[lld-macho] Rework mergeFlag to behave closer to what ld64 does.
Browse files Browse the repository at this point in the history
Details:
I've been getting a few weird errors similar to the following from our internal tests:

```
ld64.lld.darwinnew: error: Cannot merge section __eh_frame (type=0x0) into __eh_frame (type=0xB): inconsistent types
ld64.lld.darwinnew: error: Cannot merge section __eh_frame (flags=0x0) into __eh_frame (flags=0x6800000B): strict flags differ
ld64.lld.darwinnew: error: Cannot merge section __eh_frame (type=0x0) into __eh_frame (type=0xB): inconsistent types
ld64.lld.darwinnew: error: Cannot merge section __eh_frame (flags=0x0) into __eh_frame (flags=0x6800000B): strict flags differ
```

Differential Revision: https://reviews.llvm.org/D103971
  • Loading branch information
oontvoo committed Jun 17, 2021
1 parent d02bf36 commit 366df11
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 46 deletions.
49 changes: 24 additions & 25 deletions lld/MachO/ConcatOutputSection.cpp
Expand Up @@ -30,7 +30,7 @@ void ConcatOutputSection::addInput(ConcatInputSection *input) {
flags = input->flags;
} else {
align = std::max(align, input->align);
mergeFlags(input);
finalizeFlags(input);
}
inputs.push_back(input);
input->parent = this;
Expand Down Expand Up @@ -331,30 +331,29 @@ void ConcatOutputSection::writeTo(uint8_t *buf) const {
}
}

// TODO: this is most likely wrong; reconsider how section flags
// are actually merged. The logic presented here was written without
// any form of informed research.
void ConcatOutputSection::mergeFlags(InputSection *input) {
uint8_t baseType = sectionType(flags);
uint8_t inputType = sectionType(input->flags);
if (baseType != inputType)
error("Cannot merge section " + input->name + " (type=0x" +
to_hexString(inputType) + ") into " + name + " (type=0x" +
to_hexString(baseType) + "): inconsistent types");

constexpr uint32_t strictFlags = S_ATTR_DEBUG | S_ATTR_STRIP_STATIC_SYMS |
S_ATTR_NO_DEAD_STRIP | S_ATTR_LIVE_SUPPORT;
if ((input->flags ^ flags) & strictFlags)
error("Cannot merge section " + input->name + " (flags=0x" +
to_hexString(input->flags) + ") into " + name + " (flags=0x" +
to_hexString(flags) + "): strict flags differ");

// Negate pure instruction presence if any section isn't pure.
uint32_t pureMask = ~S_ATTR_PURE_INSTRUCTIONS | (input->flags & flags);

// Merge the rest
flags |= input->flags;
flags &= pureMask;
void ConcatOutputSection::finalizeFlags(InputSection *input) {
uint8_t inputType = input->flags & SECTION_TYPE;
switch (inputType) {
default /*type-unspec'ed*/:
// FIXME: Add additional logics here when supporting emitting obj files.
break;
case S_4BYTE_LITERALS:
case S_8BYTE_LITERALS:
case S_16BYTE_LITERALS:
case S_CSTRING_LITERALS:
case S_ZEROFILL:
case S_LAZY_SYMBOL_POINTERS:
case S_MOD_TERM_FUNC_POINTERS:
case S_THREAD_LOCAL_REGULAR:
case S_THREAD_LOCAL_ZEROFILL:
case S_THREAD_LOCAL_VARIABLES:
case S_THREAD_LOCAL_INIT_FUNCTION_POINTERS:
case S_THREAD_LOCAL_VARIABLE_POINTERS:
case S_NON_LAZY_SYMBOL_POINTERS:
case S_SYMBOL_STUBS:
flags |= input->flags;
break;
}
}

void ConcatOutputSection::eraseOmittedInputSections() {
Expand Down
2 changes: 1 addition & 1 deletion lld/MachO/ConcatOutputSection.h
Expand Up @@ -52,7 +52,7 @@ class ConcatOutputSection final : public OutputSection {
}

private:
void mergeFlags(InputSection *input);
void finalizeFlags(InputSection *input);

size_t size = 0;
uint64_t fileSize = 0;
Expand Down
20 changes: 0 additions & 20 deletions lld/test/MachO/builtin-rename.s
Expand Up @@ -5,14 +5,6 @@
# RUN: %t/main.s -o %t/main.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin \
# RUN: %t/renames.s -o %t/renames.o
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin \
# RUN: %t/error.s -o %t/error.o

# RUN: not %lld -o %t/error %t/main.o %t/error.o -lSystem 2>&1 | \
# RUN: FileCheck %s --check-prefix=ERROR

## Check the error diagnostic for merging mismatched section types
# ERROR: Cannot merge section __pointers (type=0x0) into __nl_symbol_ptr (type=0x6): inconsistent types

## Check that section and segment renames happen as expected
# RUN: %lld -o %t/ydata %t/main.o %t/renames.o -lSystem
Expand Down Expand Up @@ -151,18 +143,6 @@ __IMPORT__pointers:
__TEXT__StaticInit:
.space 8

#--- error.s

.section __DATA,__nl_symbol_ptr
.global __DATA__nl_symbol_ptr
__DATA__nl_symbol_ptr:
.space 8

.section __IMPORT,__pointers
.global __IMPORT__pointers
__IMPORT__pointers:
.space 8

#--- main.s
.text
.global _main
Expand Down

0 comments on commit 366df11

Please sign in to comment.