Use DataExtractor to decode SLEB128 in android_relas.
authorRahman Lavaee <rahmanl@google.com>
Fri, 22 Jan 2021 17:13:30 +0000 (09:13 -0800)
committerRahman Lavaee <rahmanl@google.com>
Thu, 28 Jan 2021 09:35:18 +0000 (01:35 -0800)
A simple refactoring patch which let us use `DataExtractor::getSLEB128` rather than using a lambda function.

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

llvm/lib/Object/ELF.cpp
llvm/test/tools/llvm-readobj/ELF/packed-relocs-errors.s

index 264f115..27a35bb 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "llvm/Object/ELF.h"
 #include "llvm/BinaryFormat/ELF.h"
-#include "llvm/Support/LEB128.h"
+#include "llvm/Support/DataExtractor.h"
 
 using namespace llvm;
 using namespace object;
@@ -373,39 +373,31 @@ ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
   Expected<ArrayRef<uint8_t>> ContentsOrErr = getSectionContents(Sec);
   if (!ContentsOrErr)
     return ContentsOrErr.takeError();
-  const uint8_t *Cur = ContentsOrErr->begin();
-  const uint8_t *End = ContentsOrErr->end();
-  if (ContentsOrErr->size() < 4 || Cur[0] != 'A' || Cur[1] != 'P' ||
-      Cur[2] != 'S' || Cur[3] != '2')
+  ArrayRef<uint8_t> Content = *ContentsOrErr;
+  if (Content.size() < 4 || Content[0] != 'A' || Content[1] != 'P' ||
+      Content[2] != 'S' || Content[3] != '2')
     return createError("invalid packed relocation header");
-  Cur += 4;
-
-  const char *ErrStr = nullptr;
-  auto ReadSLEB = [&]() -> int64_t {
-    if (ErrStr)
-      return 0;
-    unsigned Len;
-    int64_t Result = decodeSLEB128(Cur, &Len, End, &ErrStr);
-    Cur += Len;
-    return Result;
-  };
+  DataExtractor Data(Content, isLE(), ELFT::Is64Bits ? 8 : 4);
+  DataExtractor::Cursor Cur(/*Offset=*/4);
 
-  uint64_t NumRelocs = ReadSLEB();
-  uint64_t Offset = ReadSLEB();
+  uint64_t NumRelocs = Data.getSLEB128(Cur);
+  uint64_t Offset = Data.getSLEB128(Cur);
   uint64_t Addend = 0;
 
-  if (ErrStr)
-    return createError(ErrStr);
+  if (!Cur)
+    return std::move(Cur.takeError());
 
   std::vector<Elf_Rela> Relocs;
   Relocs.reserve(NumRelocs);
   while (NumRelocs) {
-    uint64_t NumRelocsInGroup = ReadSLEB();
+    uint64_t NumRelocsInGroup = Data.getSLEB128(Cur);
+    if (!Cur)
+      return std::move(Cur.takeError());
     if (NumRelocsInGroup > NumRelocs)
       return createError("relocation group unexpectedly large");
     NumRelocs -= NumRelocsInGroup;
 
-    uint64_t GroupFlags = ReadSLEB();
+    uint64_t GroupFlags = Data.getSLEB128(Cur);
     bool GroupedByInfo = GroupFlags & ELF::RELOCATION_GROUPED_BY_INFO_FLAG;
     bool GroupedByOffsetDelta = GroupFlags & ELF::RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG;
     bool GroupedByAddend = GroupFlags & ELF::RELOCATION_GROUPED_BY_ADDEND_FLAG;
@@ -413,34 +405,30 @@ ELFFile<ELFT>::android_relas(const Elf_Shdr &Sec) const {
 
     uint64_t GroupOffsetDelta;
     if (GroupedByOffsetDelta)
-      GroupOffsetDelta = ReadSLEB();
+      GroupOffsetDelta = Data.getSLEB128(Cur);
 
     uint64_t GroupRInfo;
     if (GroupedByInfo)
-      GroupRInfo = ReadSLEB();
+      GroupRInfo = Data.getSLEB128(Cur);
 
     if (GroupedByAddend && GroupHasAddend)
-      Addend += ReadSLEB();
+      Addend += Data.getSLEB128(Cur);
 
     if (!GroupHasAddend)
       Addend = 0;
 
-    for (uint64_t I = 0; I != NumRelocsInGroup; ++I) {
+    for (uint64_t I = 0; Cur && I != NumRelocsInGroup; ++I) {
       Elf_Rela R;
-      Offset += GroupedByOffsetDelta ? GroupOffsetDelta : ReadSLEB();
+      Offset += GroupedByOffsetDelta ? GroupOffsetDelta : Data.getSLEB128(Cur);
       R.r_offset = Offset;
-      R.r_info = GroupedByInfo ? GroupRInfo : ReadSLEB();
+      R.r_info = GroupedByInfo ? GroupRInfo : Data.getSLEB128(Cur);
       if (GroupHasAddend && !GroupedByAddend)
-        Addend += ReadSLEB();
+        Addend += Data.getSLEB128(Cur);
       R.r_addend = Addend;
       Relocs.push_back(R);
-
-      if (ErrStr)
-        return createError(ErrStr);
     }
-
-    if (ErrStr)
-      return createError(ErrStr);
+    if (!Cur)
+      return std::move(Cur.takeError());
   }
 
   return Relocs;
index 4f2e65e..32e96d7 100644 (file)
@@ -23,7 +23,7 @@
 .section .rela.dyn, "a", @0x60000001
 .ascii "APS2"
 
-# ERR-PAST-END: warning: '[[FILE]]': unable to read relocations from SHT_ANDROID_REL section with index 3: malformed sleb128, extends past end
+# ERR-PAST-END: warning: '[[FILE]]': unable to read relocations from SHT_ANDROID_REL section with index 3: unable to decode LEB128 at offset 0x{{([[:xdigit:]]{8})}}: malformed sleb128, extends past end
 
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t/asm3.s -o %t3.o
 # RUN: llvm-readobj --relocations %t3.o 2>&1 | FileCheck %s -DFILE=%t3.o --check-prefix=ERR-PAST-END