current commit
260929.11 · deps: update lief to 1.0.0
/* Copyright 2017 - 2026 R. Thomas
 * Copyright 2017 - 2026 Quarkslab
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <sstream>

#include "LIEF/COFF/Relocation.hpp"
#include "LIEF/COFF/Symbol.hpp"
#include "LIEF/COFF/Section.hpp"
#include "LIEF/BinaryStream/BinaryStream.hpp"

#include <spdlog/fmt/fmt.h>

#include "COFF/structures.hpp"

#include "frozen.hpp"

namespace LIEF::COFF {
std::unique_ptr<Relocation> Relocation::parse(BinaryStream& stream,
                                              Header::MACHINE_TYPES arch) {
  auto raw_reloc = stream.read<details::relocation>();
  if (!raw_reloc) {
    return nullptr;
  }
  auto reloc = std::unique_ptr<Relocation>(new Relocation());
  reloc->address_ = raw_reloc->VirtualAddress;
  reloc->symbol_idx_ = raw_reloc->SymbolTableIndex;
  reloc->type_ = from_value(raw_reloc->Type, arch);
  return reloc;
}

std::string Relocation::to_string() const {
  using fmt::format;
  std::ostringstream oss;
  oss << format("{:#010x} {:>26} {:#010x}", address(), COFF::to_string(type()),
                symbol_idx());
  if (const Symbol* sym = symbol()) {
    oss << " symbol=" << sym->name();
  }

  if (const Section* sec = section()) {
    oss << " section=" << sec->name();
  }
  return oss.str();
}

const char* to_string(Relocation::TYPE e) {
#define ENTRY(X) std::pair(Relocation::TYPE::X, #X)
  STRING_MAP enums2str{
      ENTRY(UNKNOWN),

      ENTRY(AMD64_ABSOLUTE),
      ENTRY(AMD64_ADDR32),
      ENTRY(AMD64_ADDR32NB),
      ENTRY(AMD64_ADDR64),
      ENTRY(AMD64_PAIR),
      ENTRY(AMD64_REL32),
      ENTRY(AMD64_REL32_1),
      ENTRY(AMD64_REL32_2),
      ENTRY(AMD64_REL32_3),
      ENTRY(AMD64_REL32_4),
      ENTRY(AMD64_REL32_5),
      ENTRY(AMD64_SECREL),
      ENTRY(AMD64_SECREL7),
      ENTRY(AMD64_SECTION),
      ENTRY(AMD64_SREL32),
      ENTRY(AMD64_SSPAN32),
      ENTRY(AMD64_TOKEN),

      ENTRY(ARM64_ABSOLUTE),
      ENTRY(ARM64_ADDR32),
      ENTRY(ARM64_ADDR32NB),
      ENTRY(ARM64_ADDR64),
      ENTRY(ARM64_BRANCH14),
      ENTRY(ARM64_BRANCH19),
      ENTRY(ARM64_BRANCH26),
      ENTRY(ARM64_PAGEBASE_REL21),
      ENTRY(ARM64_PAGEOFFSET_12A),
      ENTRY(ARM64_PAGEOFFSET_12L),
      ENTRY(ARM64_REL21),
      ENTRY(ARM64_REL32),
      ENTRY(ARM64_SECREL),
      ENTRY(ARM64_SECREL_HIGH12A),
      ENTRY(ARM64_SECREL_LOW12A),
      ENTRY(ARM64_SECREL_LOW12L),
      ENTRY(ARM64_SECTION),
      ENTRY(ARM64_TOKEN),

      ENTRY(ARM_ABSOLUTE),
      ENTRY(ARM_ADDR32),
      ENTRY(ARM_ADDR32NB),
      ENTRY(ARM_BLX11),
      ENTRY(ARM_BLX23T),
      ENTRY(ARM_BLX24),
      ENTRY(ARM_BRANCH11),
      ENTRY(ARM_BRANCH20T),
      ENTRY(ARM_BRANCH24),
      ENTRY(ARM_BRANCH24T),
      ENTRY(ARM_MOV32A),
      ENTRY(ARM_MOV32T),
      ENTRY(ARM_PAIR),
      ENTRY(ARM_REL32),
      ENTRY(ARM_SECREL),
      ENTRY(ARM_SECTION),
      ENTRY(ARM_TOKEN),

      ENTRY(I386_ABSOLUTE),
      ENTRY(I386_DIR16),
      ENTRY(I386_DIR32),
      ENTRY(I386_DIR32NB),
      ENTRY(I386_REL16),
      ENTRY(I386_REL32),
      ENTRY(I386_SECREL),
      ENTRY(I386_SECREL7),
      ENTRY(I386_SECTION),
      ENTRY(I386_SEG12),
      ENTRY(I386_TOKEN),

      ENTRY(MIPS_ABSOLUTE),
      ENTRY(MIPS_GPREL),
      ENTRY(MIPS_JMPADDR),
      ENTRY(MIPS_JMPADDR16),
      ENTRY(MIPS_LITERAL),
      ENTRY(MIPS_PAIR),
      ENTRY(MIPS_REFHALF),
      ENTRY(MIPS_REFHI),
      ENTRY(MIPS_REFLO),
      ENTRY(MIPS_REFWORD),
      ENTRY(MIPS_REFWORDNB),
      ENTRY(MIPS_SECREL),
      ENTRY(MIPS_SECRELHI),
      ENTRY(MIPS_SECRELLO),
      ENTRY(MIPS_SECTION),
  };
#undef ENTRY

  if (auto it = enums2str.find(e); it != enums2str.end()) {
    return it->second;
  }
  return "UNKNOWN";
}
}