Skip to content

Commit

Permalink
Merge objects in alphabetical order for determinism
Browse files Browse the repository at this point in the history
  • Loading branch information
jblazquez committed Jan 19, 2025
1 parent badafe3 commit 275f940
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 10 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ You can use armerge to handle Linux/Android archives on a macOS host if the righ

## Object merge order

By default, objects are passed to the linker in an unspecified order. Linkers typically lay out the output file's sections in the order the inputs are specified.
By default, objects are passed to the linker in alphabetical order. Linkers typically lay out the output file's sections in the order the inputs are specified. Passing the objects in alphabetical order helps make the output deterministic.

If you want to control the order in which some of the object files are merged, you can use the `--order-file` option. With this option, you can specify an order file that controls the relative order in which armerge passes the listed object files to the linker, so you can precisely control the order in which certain sections will be laid out in the output.

The order file is a plain text file with one entry per line, in the format `{INPUT_LIB}@{OBJNAME}`, where `INPUT_LIB` is the name of the input library and `OBJNAME` is the name of the object file to select from that library. Blank lines or lines starting with the `#` sign are ignored. Any object files not listed are placed after all of the listed objects in an unspecified order. For example:
The order file is a plain text file with one entry per line, in the format `{INPUT_LIB}@{OBJNAME}`, where `INPUT_LIB` is the name of the input library and `OBJNAME` is the name of the object file to select from that library. Blank lines or lines starting with the `#` sign are ignored. Any object files not listed are placed after all of the listed objects, in alphabetical order. For example:

```
# Place the custom malloc object file first
Expand All @@ -70,7 +70,7 @@ libmyallocator.a@mymalloc.o
# Place the app's entry point next
libmyapp.a@entry.o
# All other object files are placed after this in an unspecified order.
# All other object files are placed after this in alphabetical order.
```

## Principle of operation
Expand Down
8 changes: 4 additions & 4 deletions src/objects/filter_deps.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashSet};
use std::path::PathBuf;

use crate::{ArmergeKeepOrRemove, MergeError};
Expand All @@ -11,7 +11,7 @@ use crate::objects::syms::ObjectSyms;

fn add_deps_recursive(
objs_set: &mut HashSet<PathBuf>,
syms: &HashMap<PathBuf, ObjectSyms>,
syms: &BTreeMap<PathBuf, ObjectSyms>,
obj: &ObjectSyms,
) {
for dep in &obj.deps {
Expand All @@ -25,7 +25,7 @@ pub fn filter_required_objects(
objects: &[PathBuf],
keep_or_remove: ArmergeKeepOrRemove,
regexes: &[Regex],
) -> Result<HashMap<PathBuf, ObjectSyms>, MergeError> {
) -> Result<BTreeMap<PathBuf, ObjectSyms>, MergeError> {
let mut object_syms = objects
.into_par_iter()
.map(|obj_path| {
Expand All @@ -34,7 +34,7 @@ pub fn filter_required_objects(
ObjectSyms::new(obj_path, keep_or_remove, regexes)?,
))
})
.collect::<Result<HashMap<PathBuf, ObjectSyms>, _>>()?;
.collect::<Result<BTreeMap<PathBuf, ObjectSyms>, _>>()?;
ObjectSyms::check_dependencies(&mut object_syms);

let mut required_objs = HashSet::new();
Expand Down
6 changes: 3 additions & 3 deletions src/objects/syms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{ArmergeKeepOrRemove, MergeError};
use object::{Object, ObjectSymbol, SymbolKind};
use rayon::prelude::*;
use regex::Regex;
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeMap, HashSet};
use std::path::{Path, PathBuf};

pub struct ObjectSyms {
Expand Down Expand Up @@ -79,7 +79,7 @@ impl ObjectSyms {
false
}

pub fn check_dependencies(object_syms: &mut HashMap<PathBuf, Self>) {
pub fn check_dependencies(object_syms: &mut BTreeMap<PathBuf, Self>) {
let deps_map = object_syms
.par_iter()
.map(|(left_path, left_syms)| {
Expand All @@ -95,7 +95,7 @@ impl ObjectSyms {
}
(left_path.to_owned(), deps)
})
.collect::<HashMap<_, _>>();
.collect::<BTreeMap<_, _>>();
for (path, deps) in deps_map {
object_syms.get_mut(&path).unwrap().deps = deps;
}
Expand Down

0 comments on commit 275f940

Please sign in to comment.