This is an archive of the discontinued LLVM Phabricator instance.

[lld][Arm] Big Endian - Byte invariant support.
ClosedPublic

Authored by simpal01 on May 18 2023, 7:29 AM.

Details

Summary

Arm has BE8 big endian configuration called a byte-invariant(every byte has the same address on little and big-endian systems).

When in BE8 mode:

  1. Instructions are big-endian in relocatable objects but little-endian in executables and shared objects.
  2. Data is big-endian.
  3. The data encoding of the ELF file is ELFDATA2MSB.

To support BE8 without an ABI break for relocatable objects,the linker takes on the responsibility of changing the endianness of instructions. At a high level the only difference between BE32 and BE8 in the linker is that for BE8:

  1. The linker sets the flag EF_ARM_BE8 in the ELF header.
  2. The linker endian reverses the instructions, but not data.

This patch adds BE8 big endian support for Arm. To endian reverse the instructions we'll need access to the mapping symbols. Code sections can contain a mix of Arm, Thumb and literal data. We need to endian reverse Arm instructions as words, Thumb instructions
as half-words and ignore literal data.The only way to find these transitions precisely is by using mapping symbols. The instruction reversal will need to take place after relocation. For Arm BE8 code sections (Section has SHF_EXECINSTR flag ) we inserted a step after relocation to endian reverse the instructions. The implementation strategy i have used here is to write all sections BE32 including SyntheticSections then endian reverse all code in InputSections via mapping symbols.

Diff Detail

Event Timeline

simpal01 created this revision.May 18 2023, 7:29 AM
Herald added a project: Restricted Project. · View Herald Transcript
simpal01 requested review of this revision.May 18 2023, 7:29 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 18 2023, 7:29 AM

There is some similar code in the ARMErrataFix.cpp that also collects the mapping symbols. Now i have kept the code to collect Mapping symbols getArmMappingSymbolList in a generic place (Arch/ARM.cpp) so that it can be called by ARMErrataFix.cpp as well. If this decision is accepted, i will make an another patch to reflect the changes in ARMErrataFix.cpp.

simpal01 edited the summary of this revision. (Show Details)May 18 2023, 7:41 AM
simpal01 edited the summary of this revision. (Show Details)
amilendra added inline comments.May 18 2023, 9:10 AM
lld/ELF/Arch/ARM.cpp
938

getArmMappingSymbolList is called only within this file. So you can make it static.

941

InputSection?

953

Nit: InputSection

968–975

Because width does not change within the loop, checking it before the loop would be more efficient.
Something like

if (width == 4) {
  for (uint64_t i = start; i < end; i += width)
      write32le(buf + i, read32(bytes + i));
}
else if (width == 2) {
  for (uint64_t i = start; i < end; i += width) 
      write16le(buf + i, read16(bytes + i));
}

Also it would be good if the hard coded `4` and `2` can be avoided to use the `CodeState` enum. Maybe `CodeWidth` is a better name for the enum?
983

I can see some refactoring opportunities in this function.
If you use something like enum CodeState { DATA = 0, HALFWORDCODE = 2, WORDCODE = 4}; you can use
BytesexReverseInstructions(buf, start, end, cur_state); instead of hard coding width such as BytesexReverseInstructions(buf, start, end, 4); and BytesexReverseInstructions(buf, start, end, 2);

1003–1008

This can be in its own function. Maybe a lambda function? That will let you rewrite the case DATA: block like

start = msym->value;
cur_state = function(msym);
1011–1026

These two blocks can probably be folded together.

case WORDCODE:
case HALFWORDCODE:
  if (new_state != cur_state) {
    end = msym->value;
    BytesexReverseInstructions(buf, start, end, cur_state);
    cur_state = new_state;
    start = msym->value;
  }
  break;
1036–1037
ARM.cpp:1032:5: warning: default label in switch which covers all enumeration values [-Wcovered-switch-default]
    default:
amilendra added inline comments.May 18 2023, 9:28 AM
lld/ELF/Arch/ARM.cpp
938

Ah sorry. I did not see your comment that there is a chance that this can be used in ARMErrataFix.cpp as well. Ignore my comment of making it static.

I think the overall strategy looks good. I've got quite a few detailed comments. Not had a chance to go over the tests in detail yet. Will do that next week.

lld/ELF/Arch/ARM.cpp
76

A couple of nits:

  • Suggest ELF instead of elf and big-endian instead of big endian to be consistent with other comments.
  • The convention for LLD comments is to finish with a full stop.
peter.smith added inline comments.May 18 2023, 9:46 AM
lld/ELF/Arch/ARM.cpp
941

I think this should be InputSection as the map is from InputSection to defined.

953

Type IutputSection -> InputSection

965

I think toLittleEndianInstructions is a better name as this doesn't endian reverse, it converts from big-endian to little- endian.

967

Do you need bytes? It looks like neither the pointer buf or the pointer bytes is written to. For example:

write32le(buf + i, read32(buf + i));
978

I'd go with:

// Arm BE8 big endian format requires instructions to be little-endian, with the initial contents big-endian. Convert
// the big-endian instructions to little-endian leaving literal data untouched. We use mapping symbols to identify
// half open intervals of Arm code [$a, non $a) and Thumb [$t, non  $t) code and convert these to little-endian a word
// or half-word at a time respectively.
980

Mapping symbols are lower case $a instead of $A

983

Similar to the comment about the function name above. This is converting big to little endian, whereas the name implies that we are reversing.

Given that this is specific to Arm BE8 perhaps convertArmInstructionsToBE8()

985

getArmMappingSymbolList() is going to recalculate the mapping symbols for the whole program each time it is called (once per inputSection).

Given that the mapping symbols are read-only then I suggest calculating them before writing sections and storting them read-only in the ARM class or Config.

991

I suggest using an enum class using the normal variable naming convention. For example in Config.h

enum class BsymbolicKind { None, NonWeakFunctions, Functions, All };

I'd also suggest Arm, Thumb and Data for the names.

992

curState (LLVM coding standard)

996

I don't think you need to treat SyntheticSections differently as getSize is a virtual function.
length = s->getSize(); should be fine.

1002

newState (LLVM coding standard)

1009

I wonder if this could be simplified. For example

case WORDCODE:
  if (new_state == HALFWORDCODE || new_state == DATA)

Is the same as

case WORDCODE:
  if (new_state != WORDCODE)

In all cases it looks like

if (new_state == cur_state)
  continue;

Then the if statements within the case statements could be skipped as we know we are terminating a contiguous run of cur_state.

cur_state = new_state; and start=msym->value are common to all cases apart from the default case, but I think that as we only record mapping symbols in the map then default shouldn't occur.

With all that I think this could be (using your names and enum):

    if (new_state == cur_state)
      continue;

    if (cur_state == WORDCODE)
      BytesexReverseInstructions(buf, start, msym->value, 4);
    else if (cur_state == HALFWORDCODE)
      BytesexReverseInstructions(buf, start, msym->value, 2);

    start = msym->value;
    cur_state = new_state;
  }
  // Passed last mapping symbol, may need to reverse
  // up to end of section
  if (cur_state == WORDCODE)
    BytesexReverseInstructions(buf, start, length, 4);
  if (cur_state == HALFWORDCODE)
    BytesexReverseInstructions(buf, start, length, 2);
}

A further shortening could be done by using values 4, 2 and 1 for the enum (although not with an enum class without casting) then you could use that for the length

// Passed last mapping symbol, may need to reverse
 // up to end of section
 if (cur_state != DATA)
   BytesexReverseInstructions(buf, start, length, cur_state);
1041

For a couple of sentences I suggest using // rather than /* */

lld/ELF/Options.td
39

I'd go with something like "Write a Big Endian ELF file using BE8 format (Arm only)".

lld/ELF/OutputSections.cpp
499

I'd say When in Arm BE8 mode, the linker has to convert the big-endian instructions to little-endian, leaving the data big-endian.

501

I've just thought that we probably do not want to endian reverse instructions when doing a relocatable link (the -r option which maps to config->relocatable; this produces a relocatable object file). We will want to double check what GNU ld does to make sure.

503

I think this test can be folded into the first if statement.

if (config->emachine == EM_ARM && !config->isLE && config->be8 && (flags & SHF_EXECINSTR))
lld/test/ELF/emulation-arm.s
76

I think this comment needs updating. This is the test that checks that BE8 has been set.

peter.smith added inline comments.May 18 2023, 11:04 AM
lld/ELF/Options.td
39

We'll also need to add be8 to the man page llvm-project/lld/docs/ld/lld.1

Thanks for the reviews. I am away the whole next week. I will work on this review comments the week after next.

One more thought I had where we might need changes, although they could be done in a different patch as they are more of a bug fix.

The Arm thunks come in short and long forms. If a thunk is within range of a branch instruction it will write this out, otherwise it will use a longer sequence involving an indirect branch. In most thunks this doesn't change the mapping symbols, but in some cases it does because there are either state changes or inline literal data. For example:

void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
  addSymbol(saver().save("__Thumbv6MABSLongThunk_" + destination.getName()),
            STT_FUNC, 1, isec);
  addSymbol("$t", STT_NOTYPE, 0, isec);
  addSymbol("$d", STT_NOTYPE, 8, isec);
}

Note that if this is written as a short thunk then the second mapping symbol will be incorrect, and will end up overlapping with the next thunk. At the moment this may just mess the disassembly up, but with BE8 this could end up messing up the conversion to little endian.

I think that there may only be one or two thunks that have multiple mapping symbols and are used on CPUs that support BE8, however it would be good to fix all the cases. Which can be done by checking if a short thunk is being used and only adding the non 0 offset mapping symbols if short thunks aren't being used. For example, the AArch64 thunks add a check:

void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
  addSymbol(saver().save("__AArch64AbsLongThunk_" + destination.getName()),
            STT_FUNC, 0, isec);
  addSymbol("$x", STT_NOTYPE, 0, isec);
  if (!getMayUseShortThunk())
    addSymbol("$d", STT_NOTYPE, 8, isec);
}
simpal01 updated this revision to Diff 527410.Jun 1 2023, 7:13 AM

Address review comments.

simpal01 marked 26 inline comments as done.Jun 1 2023, 7:24 AM
simpal01 added inline comments.
lld/ELF/Arch/ARM.cpp
1003–1008

isArmMapSymbol, isThumbMapSymbol and isDataMapSymbol are used by both the functions convertArmInstructionstoBE8 and getArmMappingSymbolList.

1011–1026

Refactored this part of the code as suggested by Amilendra and Peter.

lld/ELF/OutputSections.cpp
501

I have checked with gcc and found that gcc does endian reverse instructions in BE8 mode when doing a relocatable link.

simpal01 marked an inline comment as done.EditedJun 1 2023, 7:24 AM

One more thought I had where we might need changes, although they could be done in a different patch as they are more of a bug fix.

The Arm thunks come in short and long forms. If a thunk is within range of a branch instruction it will write this out, otherwise it will use a longer sequence involving an indirect branch. In most thunks this doesn't change the mapping symbols, but in some cases it does because there are either state changes or inline literal data. For example:

void ThumbV6MABSLongThunk::addSymbols(ThunkSection &isec) {
  addSymbol(saver().save("__Thumbv6MABSLongThunk_" + destination.getName()),
            STT_FUNC, 1, isec);
  addSymbol("$t", STT_NOTYPE, 0, isec);
  addSymbol("$d", STT_NOTYPE, 8, isec);
}

Note that if this is written as a short thunk then the second mapping symbol will be incorrect, and will end up overlapping with the next thunk. At the moment this may just mess the disassembly up, but with BE8 this could end up messing up the conversion to little endian.

I think that there may only be one or two thunks that have multiple mapping symbols and are used on CPUs that support BE8, however it would be good to fix all the cases. Which can be done by checking if a short thunk is being used and only adding the non 0 offset mapping symbols if short thunks aren't being used. For example, the AArch64 thunks add a check:

void AArch64ABSLongThunk::addSymbols(ThunkSection &isec) {
  addSymbol(saver().save("__AArch64AbsLongThunk_" + destination.getName()),
            STT_FUNC, 0, isec);
  addSymbol("$x", STT_NOTYPE, 0, isec);
  if (!getMayUseShortThunk())
    addSymbol("$d", STT_NOTYPE, 8, isec);
}

I have added these changes as well into this patch. I am not quite sure what you mean by non 0 offset mapping symbols here. There are places where we are adding three mapping symbols($a, $t and $d). In that cases i added the check like below.

addSymbol("$t", STT_NOTYPE, 0, isec);
addSymbol("$a", STT_NOTYPE, 4, isec);
if (!getMayUseShortThunk())
  addSymbol("$d", STT_NOTYPE, 12, isec);
MaskRay added inline comments.Jun 1 2023, 8:42 AM
lld/ELF/Arch/ARM.cpp
24

Move CodeState into the end of the anonymous namespace

Make sectionMap static after the anonymous namespace.

https://llvm.org/docs/CodingStandards.html#anonymous-namespaces

26

std::vector => SmallVector<const Defined *, 0>

939

in.symTab will be null with --strip-all

945

cast_if_present

985

Don't add blank line between local variable declarations

987

Delete this blank line.

995

if (isDataMapSymbol(msym)) is unneeded.

1012

length is uncommon in lld. Use size.

lld/ELF/Config.h
204

bool armBe8 = false;

lld/ELF/Options.td
39

format(Arm only) => format (AArch32 only)

lld/ELF/Target.h
226

...List is uncommon in lld code. use the plural form Symbols

lld/docs/ld.lld.1
92

(AArch32 only)

lld/test/ELF/arm-plt-reloc.s
260

Omit addresses that are not significant. These addresses make test updating difficult if text section addresses change.

MaskRay added inline comments.Jun 1 2023, 9:29 AM
lld/test/ELF/arm-be8-check.s
1 ↗(On Diff #527410)

What's the purpose of the new test when there are other thunk tests have got the --be8 test?

lld/test/ELF/arm-be8-thunks.s
1 ↗(On Diff #527410)

What's the purpose of the new test when there are other thunk tests have got the --be8 test?

Should there be an error when --be8 is used by non-EM_ARM or little-endian? You may add arm-be8.s

Instructions are big-endian in objects but little-endian in executables.
Data is big-endian.
ELF files are big-endian.

Instructions are big-endian in relocatable object files but little-endian in executables and shared objects. ("objects files" include executable files and shared object files as well)
Data is big-endian.
The data encoding of the ELF files is ELFDATA2MSB

simpal01 updated this revision to Diff 529205.Jun 7 2023, 12:56 AM

Addressed review comments.

simpal01 marked 12 inline comments as done.Jun 7 2023, 1:22 AM
simpal01 added inline comments.
lld/ELF/Arch/ARM.cpp
939

Yeah. you are right. I didn't notice that until you say. Thank you. Now i am collecting mapping symbols separately between synthetic and non synthetic local symbols. Adding Linker generated mapping symbols through the function addArmMappingSymbols() when linker generated symbols are added via addSyntheticLocal.

lld/test/ELF/arm-be8-check.s
1 ↗(On Diff #527410)

Removed this test

lld/test/ELF/arm-be8-thunks.s
1 ↗(On Diff #527410)

there were not any test which checks the hex dump content of the executable sections. Now moved this checking to arm-thunk-reuse.s

simpal01 marked 2 inline comments as done.EditedJun 7 2023, 1:22 AM

Should there be an error when --be8 is used by non-EM_ARM or little-endian? You may add arm-be8.s

Done. Added the checking in target-specific-options.s. We have similar checks in the same test file.

simpal01 edited the summary of this revision. (Show Details)EditedJun 7 2023, 1:27 AM

Instructions are big-endian in objects but little-endian in executables.
Data is big-endian.
ELF files are big-endian.

Instructions are big-endian in relocatable object files but little-endian in executables and shared objects. ("objects files" include executable files and shared object files as well)
Data is big-endian.
The data encoding of the ELF files is ELFDATA2MSB

Updated the summary accordingly.

Only a small comment about making sure the mapping symbols remain sorted when adding symbols later.

lld/ELF/Arch/ARM.cpp
969

We are only adding a single symbol, whereas the name addArmMappingSymbols implies many symbols.

We should also be careful with using push_back here as we need to make sure that the mapping symbols are sorted. As it happens the way the code is used today push_back is fine as we always add the symbols in ascending order, but it would be easy to make a mistake in the future.

Possible solutions include:

  • use insert rather than push_back
  • sort the section map for the section after push_back
  • possibly delay the sorting of the mapping symbols till the first use.
  • change the name to push rather than add, make sure there is a comment to state that symbols must be pushed in ascending order.
simpal01 added inline comments.Jun 12 2023, 6:01 AM
lld/ELF/Arch/ARM.cpp
969

I am sorting the mapping symbols already in this patch just before using it. I have introduced a new function named sortArmMappingSymbols which calls inside getArmMappingSymbols. By this time all the local and synthetic mapping symbols are added into the sectionmap. Sorry i could have been mentioned about it in my previous comments.

peter.smith added inline comments.Jun 12 2023, 6:15 AM
lld/ELF/Arch/ARM.cpp
969

I am sorting the mapping symbols already in this patch just before using it. I have introduced a new function named sortArmMappingSymbols which calls inside getArmMappingSymbols. By this time all the local and synthetic mapping symbols are added into the sectionmap. Sorry i could have been mentioned about it in my previous comments.

OK, I missed that getMappingSymbols() is called after addArmMappingSymbols().

Although a little bit more code, one suggestion is to split getArmMappingSymbols into two functions
addArmInputSectionMappingSymbols();
sortArmMappingSymbols();

Which makes it clear at the call-site what is going on.

Looking at the name alone getArmMappingSymbols() doesn't hint at the side-effect of sorting the mapping symbols. Really it is addArmInputSectionMappingSymbolsThenSort()

simpal01 updated this revision to Diff 530801.EditedJun 13 2023, 12:51 AM

Addressing review comments.

  1. Rename the following functions getArmMappingSymbols -> addArmInputSectionMappingSymbolsThenSort addArmMappingSymbols -> addSyntheticSectionMappingSymbol
  1. Split getArmMappingSymbols into two functions. addArmInputSectionMappingSymbols() and sortArmMappingSymbols()
simpal01 marked 2 inline comments as done.Jun 13 2023, 12:56 AM
simpal01 added inline comments.
lld/ELF/Arch/ARM.cpp
969

Renamed the functions. Since the mapping symbols are sorting before first use, i hope push_back is fine to use and no need to change to insert.

A few small follow up comments. I don't have anything beyond comments or naming. So hopefully can approve next round.

lld/ELF/Arch/ARM.cpp
973

Suggest changing the comment to explain why. For example:

Synthetic Sections are not backed by an ELF file where we can access the symbol table, instead mapping symbols added to Synthetic Sections are stored in the Synthetic Symbol Table. Due to the presence of strip, we cannot rely on the Synthetic Symbol Table retaining the mapping symbols. Instead we record the mapping symbols locally.
lld/ELF/Options.td
39

Looks like this line is missing a space between format and (AArch32 only)

lld/ELF/Target.h
221

It would be good to keep the Arm BE8 functionality together in a single chunk. Consider moving to where the other two functions are, or moving the other two up here.

lld/ELF/Writer.cpp
2151

I have a mild preference for making sortArmMappingSymbols() non static and doing:
if (config->emachine == EM_ARM && !config->isLE && config->armBe8) {

addArmInputSectionMappingSymbols();
sortArmMappingSymbols();

}

But that isn't a strong opinion, feel free to keep this if you prefer.

simpal01 updated this revision to Diff 531264.Jun 14 2023, 4:59 AM
simpal01 marked an inline comment as done.

Addressing review comments.

simpal01 marked 4 inline comments as done.Jun 14 2023, 5:00 AM
peter.smith accepted this revision.Jun 14 2023, 9:17 AM

LGTM, one typo fix, but this can be done prior to commit. Will be good to wait a few days to give MaskRay a chance to leave any final comments.

lld/ELF/Arch/ARM.cpp
972

typo locallly -> locally.

This revision is now accepted and ready to land.Jun 14 2023, 9:17 AM
simpal01 updated this revision to Diff 532880.Jun 20 2023, 6:05 AM

typo locallly -> locally.

Since there is no new comments after Peter approved this patch, i am going to submit this. If there is any more comments later, i can work on that as a separate patch.

This revision was landed with ongoing or failed builds.Jun 20 2023, 6:08 AM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Jun 20 2023, 6:17 AM

This makes lld sigsegv during check-lld: http://45.33.8.238/linux/110197/step_11.txt

Please take a look and revert for now if it takes a while to fix.

The bot recovered after https://github.com/llvm/llvm-project/compare/1d27ad207744...2efdacf74c54 , but that looks fairly unrelated. So maybe it's accidentally hiding a bug. Maybe run tests with asan (or similar) enabled to make sure there aren't issues in this patch.

Thank you for the heads up. I had tested everything locally before landing the changes. Not sure what caused the premege check to fail. Yes as you said i will run the tests with asan enabled and see . Thanks.

hctim added a subscriber: hctim.Jun 20 2023, 9:26 AM

Hi, looks like this broke the sanitizer buildbots: https://lab.llvm.org/buildbot/#/builders/5/builds/34555/steps/10/logs/stdio

Full instructions on how to reproduce the bot can be found here: https://github.com/google/sanitizers/wiki/SanitizerBotReproduceBuild. The script used in that bit is buildbot_fast.sh.

In saying that, you should be able to reproduce quicker by using:

$ cmake \
-DLLVM_ENABLE_ASSERTIONS=ON \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
-DLLVM_USE_LINKER=lld \
-GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-fsanitize=undefined" \
-DCMAKE_CXX_FLAGS="-fsanitize=undefined" \
-DLLVM_ENABLE_PROJECTS="'clang;lld;libc'" \
-DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \
-DLLVM_LIBC_ENABLE_LINTING=OFF \
-DLLVM_USE_SANITIZER=Undefined \
/path/to/llvm/llvm
$ LIT_OPTS='--filter arm-data-relocs.s' ninja check-lld
******************** TEST 'lld :: ELF/arm-data-relocs.s' FAILED ********************
Script:
--
: 'RUN: at line 2';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/arm-data-relocs.s -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.o
: 'RUN: at line 3';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/Inputs/abs256.s -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp256.o
: 'RUN: at line 4';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld.lld /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp256.o -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp
: 'RUN: at line 5';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-objdump -s /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp | /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/arm-data-relocs.s --check-prefixes=CHECK,LE
: 'RUN: at line 7';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/arm-data-relocs.s -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be.o
: 'RUN: at line 8';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-mc -filetype=obj -triple=armv7aeb-none-linux-gnueabi /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/Inputs/abs256.s -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp256.be.o
: 'RUN: at line 9';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld.lld /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be.o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp256.be.o -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be
: 'RUN: at line 10';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-objdump -s /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be | /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/arm-data-relocs.s --check-prefixes=CHECK,BE
: 'RUN: at line 12';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/ld.lld --be8 /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be.o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp256.be.o -o /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be8
: 'RUN: at line 13';   /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/llvm-objdump -s /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/tools/lld/test/ELF/Output/arm-data-relocs.s.tmp.be8 | /b/sanitizer-x86_64-linux-fast/build/llvm_build_asan_ubsan/bin/FileCheck /b/sanitizer-x86_64-linux-fast/build/llvm-project/lld/test/ELF/arm-data-relocs.s --check-prefixes=CHECK,BE
--
Exit Code: 1
Command Output (stderr):
--
/b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/include/llvm/ADT/DenseMap.h:656:46: runtime error: applying non-zero offset 696 to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /b/sanitizer-x86_64-linux-fast/build/llvm-project/llvm/include/llvm/ADT/DenseMap.h:656:46 in

f146763e0788f84de227623d87adccd5890ecdc6 Revert "Revert "[lld][Arm] Big Endian - Byte invariant support.""

The convention is to use reland and include the original description (including Differential Revision: ) in the reland commit.
You may additionally state what has been fixed.