Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ jobs:
name: test
runs-on: ubuntu-latest
timeout-minutes: 10
env:
RUSTFLAGS: -Dwarnings
RUST_BACKTRACE: full
steps:
- uses: actions/checkout@v3
- name: Clippy
run: |
cargo clippy -- -Dwarnings
- name: Test
run: |
cargo test
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ar_archive_writer"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
license = "Apache-2.0 WITH LLVM-exception"
description = "A writer for object file ar archives"
Expand All @@ -11,9 +11,9 @@ repository = "https://github.com/rust-lang/ar_archive_writer"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
object = { version = "0.32.0", default-features = false, features = ["std", "read"] }
object = { version = "0.35.0", default-features = false, features = ["std", "read"] }

[dev-dependencies]
cargo-binutils = "0.3.6"
object = { version = "0.32.0", default-features = false, features = ["write", "xcoff"] }
object = { version = "0.35.0", default-features = false, features = ["write", "xcoff"] }
pretty_assertions = "1.4.0"
9 changes: 4 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# A writer for object file ar archives

This is a Rust port of LLVM's archive writer (`ArchiveWriter.cpp`):
* Based on commit [8ef3e895a](https://github.com/llvm/llvm-project/tree/3d3ef9d073e1e27ea57480b371b7f5a9f5642ed2) (15.0.0-rc3).
* With the following options removed:
* Deterministic: always enabled.
* Symbol tables: always enabled.
This is a Rust port of LLVM's archive writer (see [the LLVM Reference](reference/Readme.md)
for details) with the following options removed:
* Deterministic: always enabled.
* Symbol tables: always enabled.

## License

Expand Down
37 changes: 25 additions & 12 deletions src/Alignment.h → reference/Alignment.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// Copied from https://github.com/llvm/llvm-project/blob/3d3ef9d073e1e27ea57480b371b7f5a9f5642ed2/llvm/include/llvm/Support/Alignment.h

//===-- llvm/Support/Alignment.h - Useful alignment functions ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
Expand All @@ -23,9 +21,9 @@
#ifndef LLVM_SUPPORT_ALIGNMENT_H_
#define LLVM_SUPPORT_ALIGNMENT_H_

#include "llvm/ADT/Optional.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <optional>
#ifndef NDEBUG
#include <string>
#endif // NDEBUG
Expand Down Expand Up @@ -95,14 +93,14 @@ struct Align {
}

/// Allow constructions of constexpr Align.
template <size_t kValue> constexpr static LogValue Constant() {
template <size_t kValue> constexpr static Align Constant() {
return LogValue{static_cast<uint8_t>(CTLog2<kValue>())};
}

/// Allow constructions of constexpr Align from types.
/// Compile time equivalent to Align(alignof(T)).
template <typename T> constexpr static LogValue Of() {
return Constant<std::alignment_of<T>::value>();
template <typename T> constexpr static Align Of() {
return Constant<std::alignment_of_v<T>>();
}

/// Constexpr constructor from LogValue type.
Expand All @@ -116,9 +114,9 @@ inline Align assumeAligned(uint64_t Value) {

/// This struct is a compact representation of a valid (power of two) or
/// undefined (0) alignment.
struct MaybeAlign : public llvm::Optional<Align> {
struct MaybeAlign : public std::optional<Align> {
private:
using UP = llvm::Optional<Align>;
using UP = std::optional<Align>;

public:
/// Default is undefined.
Expand All @@ -130,9 +128,8 @@ struct MaybeAlign : public llvm::Optional<Align> {
MaybeAlign(MaybeAlign &&Other) = default;
MaybeAlign &operator=(MaybeAlign &&Other) = default;

/// Use llvm::Optional<Align> constructor.
using UP::UP;

constexpr MaybeAlign(std::nullopt_t None) : UP(None) {}
constexpr MaybeAlign(Align Value) : UP(Value) {}
explicit MaybeAlign(uint64_t Value) {
assert((Value == 0 || llvm::isPowerOf2_64(Value)) &&
"Alignment is neither 0 nor a power of 2");
Expand Down Expand Up @@ -294,6 +291,22 @@ bool operator>=(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
bool operator<(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
bool operator>(MaybeAlign Lhs, MaybeAlign Rhs) = delete;

// Allow equality comparisons between Align and MaybeAlign.
inline bool operator==(MaybeAlign Lhs, Align Rhs) { return Lhs && *Lhs == Rhs; }
inline bool operator!=(MaybeAlign Lhs, Align Rhs) { return !(Lhs == Rhs); }
inline bool operator==(Align Lhs, MaybeAlign Rhs) { return Rhs == Lhs; }
inline bool operator!=(Align Lhs, MaybeAlign Rhs) { return !(Rhs == Lhs); }
// Allow equality comparisons with MaybeAlign.
inline bool operator==(MaybeAlign Lhs, MaybeAlign Rhs) {
return (Lhs && Rhs && (*Lhs == *Rhs)) || (!Lhs && !Rhs);
}
inline bool operator!=(MaybeAlign Lhs, MaybeAlign Rhs) { return !(Lhs == Rhs); }
// Allow equality comparisons with std::nullopt.
inline bool operator==(MaybeAlign Lhs, std::nullopt_t) { return !bool(Lhs); }
inline bool operator!=(MaybeAlign Lhs, std::nullopt_t) { return bool(Lhs); }
inline bool operator==(std::nullopt_t, MaybeAlign Rhs) { return !bool(Rhs); }
inline bool operator!=(std::nullopt_t, MaybeAlign Rhs) { return bool(Rhs); }

#ifndef NDEBUG
// For usage in LLVM_DEBUG macros.
inline std::string DebugStr(const Align &A) {
Expand All @@ -311,4 +324,4 @@ inline std::string DebugStr(const MaybeAlign &MA) {

} // namespace llvm

#endif // LLVM_SUPPORT_ALIGNMENT_H_
#endif // LLVM_SUPPORT_ALIGNMENT_H_
24 changes: 14 additions & 10 deletions src/Archive.h → reference/Archive.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// Copied from https://github.com/llvm/llvm-project/blob/3d3ef9d073e1e27ea57480b371b7f5a9f5642ed2/llvm/include/llvm/Object/Archive.h

//===- Archive.h - ar archive file format -----------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
Expand Down Expand Up @@ -30,9 +28,6 @@
#include <vector>

namespace llvm {

template <typename T> class Optional;

namespace object {

const char ArchiveMagic[] = "!<arch>\n";
Expand Down Expand Up @@ -307,6 +302,7 @@ class Archive : public Binary {
StringRef getName() const;
Expected<Child> getMember() const;
Symbol getNext() const;
bool isECSymbol() const;
};

class symbol_iterator {
Expand Down Expand Up @@ -357,16 +353,19 @@ class Archive : public Binary {
return make_range(symbol_begin(), symbol_end());
}

Expected<iterator_range<symbol_iterator>> ec_symbols() const;

static bool classof(Binary const *v) { return v->isArchive(); }

// check if a symbol is in the archive
Expected<Optional<Child>> findSym(StringRef name) const;
Expected<std::optional<Child>> findSym(StringRef name) const;

virtual bool isEmpty() const;
bool hasSymbolTable() const;
StringRef getSymbolTable() const { return SymbolTable; }
StringRef getStringTable() const { return StringTable; }
uint32_t getNumberOfSymbols() const;
uint32_t getNumberOfECSymbols() const;
virtual uint64_t getFirstChildOffset() const { return getArchiveMagicLen(); }

std::vector<std::unique_ptr<MemoryBuffer>> takeThinBuffers() {
Expand All @@ -382,6 +381,7 @@ class Archive : public Binary {
void setFirstRegular(const Child &C);

StringRef SymbolTable;
StringRef ECSymbolTable;
StringRef StringTable;

private:
Expand Down Expand Up @@ -410,17 +410,21 @@ class BigArchive : public Archive {
const FixLenHdr *ArFixLenHdr;
uint64_t FirstChildOffset = 0;
uint64_t LastChildOffset = 0;
std::string MergedGlobalSymtabBuf;
bool Has32BitGlobalSymtab = false;
bool Has64BitGlobalSymtab = false;

public:
BigArchive(MemoryBufferRef Source, Error &Err);
uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
uint64_t getLastChildOffset() const { return LastChildOffset; }
bool isEmpty() const override {
return Data.getBufferSize() == sizeof(FixLenHdr);
};
bool isEmpty() const override { return getFirstChildOffset() == 0; }

bool has32BitGlobalSymtab() { return Has32BitGlobalSymtab; }
bool has64BitGlobalSymtab() { return Has64BitGlobalSymtab; }
};

} // end namespace object
} // end namespace llvm

#endif // LLVM_OBJECT_ARCHIVE_H
#endif // LLVM_OBJECT_ARCHIVE_H
Loading