test_elf_image_builder.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_DEBUG_TEST_ELF_IMAGE_BUILDER_H_
  5. #define BASE_DEBUG_TEST_ELF_IMAGE_BUILDER_H_
  6. #include <elf.h>
  7. #include <cstdint>
  8. #include <string>
  9. #include <vector>
  10. #include "base/containers/span.h"
  11. #include "base/optional.h"
  12. #include "base/strings/string_piece.h"
  13. #if __SIZEOF_POINTER__ == 4
  14. using Addr = Elf32_Addr;
  15. using Ehdr = Elf32_Ehdr;
  16. using Half = Elf32_Half;
  17. using Off = Elf32_Off;
  18. using Phdr = Elf32_Phdr;
  19. using Word = Elf32_Word;
  20. #else
  21. using Addr = Elf64_Addr;
  22. using Ehdr = Elf64_Ehdr;
  23. using Half = Elf64_Half;
  24. using Off = Elf64_Off;
  25. using Phdr = Elf64_Phdr;
  26. using Word = Elf64_Word;
  27. #endif
  28. namespace base {
  29. // In-memory ELF image constructed by TestElfImageBuilder.
  30. class TestElfImage {
  31. public:
  32. // |buffer| is a memory buffer containing the ELF image. |elf_start| is the
  33. // start address of the ELF image within the buffer.
  34. TestElfImage(std::vector<uint8_t> buffer, const void* elf_start);
  35. ~TestElfImage();
  36. TestElfImage(TestElfImage&&);
  37. TestElfImage& operator=(TestElfImage&&);
  38. // The start address of the ELF image.
  39. const void* elf_start() const { return elf_start_; }
  40. private:
  41. std::vector<uint8_t> buffer_;
  42. const void* elf_start_;
  43. };
  44. // Builds an in-memory image of an ELF file for testing.
  45. class TestElfImageBuilder {
  46. public:
  47. // The type of mapping to use for virtual addresses in the ELF file.
  48. enum MappingType {
  49. RELOCATABLE, // Virtual address == file offset.
  50. RELOCATABLE_WITH_BIAS, // Virtual address == file offset + load bias.
  51. NON_RELOCATABLE, // Virtual address == mapped address.
  52. };
  53. // The load bias to use for RELOCATABLE_WITH_BIAS. 0xc000 is a commonly used
  54. // load bias for Android system ELF images.
  55. static constexpr size_t kLoadBias = 0xc000;
  56. explicit TestElfImageBuilder(MappingType mapping_type);
  57. ~TestElfImageBuilder();
  58. TestElfImageBuilder(const TestElfImageBuilder&) = delete;
  59. TestElfImageBuilder& operator=(const TestElfImageBuilder&) = delete;
  60. // Add a PT_LOAD segment with the specified rwx |flags|. The contents will be
  61. // filled with |size| bytes of zeros.
  62. TestElfImageBuilder& AddLoadSegment(Word flags, size_t size);
  63. // Add a PT_NOTE segment with the specified state.
  64. TestElfImageBuilder& AddNoteSegment(Word type,
  65. StringPiece name,
  66. span<const uint8_t> desc);
  67. // Adds a DT_SONAME dynamic section and the necessary state to support it. May
  68. // be invoked at most once.
  69. TestElfImageBuilder& AddSoName(StringPiece soname);
  70. TestElfImage Build();
  71. private:
  72. // Properties of a load segment to create.
  73. struct LoadSegment;
  74. // Computed sizing state for parts of the ELF image.
  75. struct ImageMeasures;
  76. // Gets the 'virtual address' corresponding to |offset| to write into the
  77. // image, according to |mapping_type_|. Relocatable ELF images have virtual
  78. // addresses equal to the offset with a possible constant load bias.
  79. // Non-relocatable ELF images have virtual addresses equal to the actual
  80. // memory address.
  81. Addr GetVirtualAddressForOffset(Off offset, const uint8_t* elf_start) const;
  82. // Measures sizes/start offset of segments in the image.
  83. ImageMeasures MeasureSizesAndOffsets() const;
  84. // Appends a header of type |T| at |loc|, a memory address within the ELF
  85. // image being constructed, and returns the address past the header.
  86. template <typename T>
  87. static uint8_t* AppendHdr(const T& hdr, uint8_t* loc);
  88. Ehdr CreateEhdr(Half phnum);
  89. Phdr CreatePhdr(Word type,
  90. Word flags,
  91. size_t align,
  92. Off offset,
  93. Addr vaddr,
  94. size_t size);
  95. const MappingType mapping_type_;
  96. std::vector<std::vector<uint8_t>> note_contents_;
  97. std::vector<LoadSegment> load_segments_;
  98. Optional<std::string> soname_;
  99. };
  100. } // namespace base
  101. #endif // BASE_DEBUG_TEST_ELF_IMAGE_BUILDER_H_