Skip to content

Commit

Permalink
Code changes to get the code to compile under GCC.
Browse files Browse the repository at this point in the history
Courgette still only knows how to compress Windows x86 executables.
But now you can compress them on linux.

BUG=none
TEST=none

Review URL: http://codereview.chromium.org/149597

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21042 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
sra@google.com committed Jul 18, 2009
1 parent 4efe77c commit 54f1b82
Show file tree
Hide file tree
Showing 18 changed files with 106 additions and 102 deletions.
1 change: 1 addition & 0 deletions build/all.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
'../third_party/harfbuzz/harfbuzz.gyp:*',
'../tools/gtk_clipboard_dump/gtk_clipboard_dump.gyp:*',
'../tools/xdisplaycheck/xdisplaycheck.gyp:*',
'../courgette/courgette.gyp:*',
],
}],
['OS=="win"', {
Expand Down
21 changes: 12 additions & 9 deletions courgette/adjustment_method_2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class LabelInfo {
// output. The pair (is_model_, debug_index_) is
// unique.

uint32 refs_; // Number of times this Label is referenced.
int refs_; // Number of times this Label is referenced.

LabelInfo* assignment_; // Label from other program corresponding to this.

Expand Down Expand Up @@ -403,10 +403,14 @@ class Shingle {
OwningSet* owning_set) {
std::pair<OwningSet::iterator, bool> pair =
owning_set->insert(Shingle(trace, position));
// pair.first is the newly inserted Shingle or the previouly inserted one
// that looks the same according to the comparator.
pair.first->add_position(position);
return &*pair.first;
// pair.first iterator 'points' to the newly inserted Shingle or the
// previouly inserted one that looks the same according to the comparator.

// const_cast required because key is const. We modify the Shingle
// extensively but not in a way that affects InterningLess.
Shingle* shingle = const_cast<Shingle*>(&*pair.first);
shingle->add_position(position);
return shingle;
}

LabelInfo* at(size_t i) const { return trace_[exemplar_position_ + i]; }
Expand Down Expand Up @@ -957,7 +961,8 @@ class AssignmentProblem {
for (Shingle::OwningSet::iterator p = shingle_instances_.begin();
p != shingle_instances_.end();
++p) {
Reclassify(&*p);
// GCC's set<T>::iterator::operator *() returns a const object.
Reclassify(const_cast<Shingle*>(&*p));
}
}

Expand Down Expand Up @@ -1035,8 +1040,6 @@ class AssignmentProblem {
void AddPatternToLabelQueue(const ShinglePattern* pattern, int sign) {
// For each possible assignment in this pattern, update the potential
// contributions to the LabelInfo queues.
size_t model_histogram_size = pattern->model_histogram_.size();
size_t program_histogram_size = pattern->program_histogram_.size();

// We want to find for each symbol (LabelInfo) the maximum contribution that
// could be achieved by making shingle-wise assignments between shingles in
Expand All @@ -1053,7 +1056,7 @@ class AssignmentProblem {
// assignments are blocked by previous incompatible assignments. We want to
// avoid a combinatorial search, so we ignore the blocking.

const int kUnwieldy = 5;
const size_t kUnwieldy = 5;

typedef std::map<LabelInfo*, int> LabelToScore;
typedef std::map<LabelInfo*, LabelToScore > ScoreSet;
Expand Down
9 changes: 4 additions & 5 deletions courgette/assembly_program.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ class InstructionWithLabel : public Instruction {
} // namespace

AssemblyProgram::AssemblyProgram()
: image_base_(0),
byte_instruction_cache_(NULL) {
: byte_instruction_cache_(NULL),
image_base_(0) {
}

static void DeleteContainedLabels(const RVAToLabel& labels) {
Expand Down Expand Up @@ -209,9 +209,9 @@ void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) {
int used = 0;

for (RVAToLabel::iterator p = labels->begin(); p != labels->end(); ++p) {
size_t index = p->second->index_;
int index = p->second->index_;
if (index != Label::kNoIndex) {
while (index >= available.size())
while (static_cast<size_t>(index) >= available.size())
available.push_back(true);
available.at(index) = false;
++used;
Expand Down Expand Up @@ -244,7 +244,6 @@ void AssemblyProgram::AssignRemainingIndexes(RVAToLabel* labels) {
// label?
//
int fill_backward_count = 0;
int backward_refs = 0;
prev = 0;
for (RVAToLabel::reverse_iterator p = labels->rbegin();
p != labels->rend();
Expand Down
13 changes: 8 additions & 5 deletions courgette/courgette.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
#ifndef COURGETTE_COURGETTE_H_
#define COURGETTE_COURGETTE_H_

#include <stddef.h> // Required to define size_t on GCC

#include "base/file_path.h"

namespace courgette {

// Status codes for Courgette APIs.
Expand Down Expand Up @@ -44,8 +48,6 @@ enum Status {
C_DISASSEMBLY_FAILED = 25, //
C_ASSEMBLY_FAILED = 26, //
C_ADJUSTMENT_FAILED = 27, //


};

class SinkStream;
Expand All @@ -67,9 +69,10 @@ Status ApplyEnsemblePatch(SourceStream* old, SourceStream* patch,
// Returns C_OK unless something went wrong.
// This function first validates that the patch file has a proper header, so the
// function can be used to 'try' a patch.
Status ApplyEnsemblePatch(const wchar_t* old_file_name,
const wchar_t* patch_file_name,
const wchar_t* new_file_name);

Status ApplyEnsemblePatch(const FilePath::CharType* old_file_name,
const FilePath::CharType* patch_file_name,
const FilePath::CharType* new_file_name);

// Generates a patch that will transform the bytes in |old| into the bytes in
// |target|.
Expand Down
4 changes: 4 additions & 0 deletions courgette/courgette_minimal_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ void Problem(const char* message) {
exit(1);
}

#if defined(OS_WIN)
int wmain(int argc, const wchar_t* argv[]) {
#else
int main(int argc, const char* argv[]) {
#endif
if (argc != 4)
UsageProblem("bad args");

Expand Down
19 changes: 16 additions & 3 deletions courgette/courgette_tool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ void Problem(const char* format, ...) {
}

std::string ReadOrFail(const std::wstring& file_name, const char* kind) {
#if defined(OS_WIN)
FilePath file_path(file_name);
#else
FilePath file_path(WideToASCII(file_name));
#endif
std::string buffer;
if (!file_util::ReadFileToString(file_path, &buffer))
Problem("Can't read %s file.", kind);
Expand All @@ -54,14 +58,18 @@ std::string ReadOrFail(const std::wstring& file_name, const char* kind) {

void WriteSinkToFile(const courgette::SinkStream *sink,
const std::wstring& output_file) {
#if defined(OS_WIN)
FilePath output_path(output_file);
#else
FilePath output_path(WideToASCII(output_file));
#endif
int count =
file_util::WriteFile(output_path,
reinterpret_cast<const char*>(sink->Buffer()),
sink->Length());
if (count == -1)
Problem("Cant write output.");
if (count != sink->Length())
Problem("Can't write output.");
if (static_cast<size_t>(count) != sink->Length())
Problem("Incomplete write.");
}

Expand Down Expand Up @@ -330,6 +338,11 @@ void ApplyBSDiffPatch(const std::wstring& old_file,
WriteSinkToFile(&new_stream, new_file);
}

bool WideStringToInt(const std::wstring& str, int *output) {
string16 copy(str.begin(), str.end());
return StringToInt(copy, output);
}

int main(int argc, const char* argv[]) {
base::AtExitManager at_exit_manager;
CommandLine::Init(argc, argv);
Expand All @@ -352,7 +365,7 @@ int main(int argc, const char* argv[]) {
int repeat_count = 1;
std::wstring repeat_switch = command_line.GetSwitchValue(L"repeat");
if (!repeat_switch.empty())
if (!StringToInt(repeat_switch, &repeat_count))
if (!WideStringToInt(repeat_switch, &repeat_count))
repeat_count = 1;

if (cmd_dis + cmd_asm + cmd_disadj + cmd_make_patch + cmd_apply_patch +
Expand Down
8 changes: 4 additions & 4 deletions courgette/difference_estimator_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ TEST(DifferenceEstimatorTest, TestSame) {
difference_estimator.MakeBase(Region(kString1, sizeof(kString1)));
DifferenceEstimator::Subject* subject =
difference_estimator.MakeSubject(Region(kString2, sizeof(kString2)));
EXPECT_EQ(0, difference_estimator.Measure(base, subject));
EXPECT_EQ(0U, difference_estimator.Measure(base, subject));
}

TEST(DifferenceEstimatorTest, TestDifferent) {
Expand All @@ -32,7 +32,7 @@ TEST(DifferenceEstimatorTest, TestDifferent) {
difference_estimator.MakeBase(Region(kString1, sizeof(kString1)));
DifferenceEstimator::Subject* subject =
difference_estimator.MakeSubject(Region(kString2, sizeof(kString2)));
EXPECT_EQ(10, difference_estimator.Measure(base, subject));
EXPECT_EQ(10U, difference_estimator.Measure(base, subject));
}

TEST(DifferenceEstimatorTest, TestDifferentSuperstring) {
Expand All @@ -43,7 +43,7 @@ TEST(DifferenceEstimatorTest, TestDifferentSuperstring) {
difference_estimator.MakeBase(Region(kString1, sizeof(kString1)-1));
DifferenceEstimator::Subject* subject =
difference_estimator.MakeSubject(Region(kString2, sizeof(kString2)-1));
EXPECT_EQ(1, difference_estimator.Measure(base, subject));
EXPECT_EQ(1U, difference_estimator.Measure(base, subject));
}

TEST(DifferenceEstimatorTest, TestDifferentSubstring) {
Expand All @@ -54,5 +54,5 @@ TEST(DifferenceEstimatorTest, TestDifferentSubstring) {
difference_estimator.MakeBase(Region(kString1, sizeof(kString1)-1));
DifferenceEstimator::Subject* subject =
difference_estimator.MakeSubject(Region(kString2, sizeof(kString2)-1));
EXPECT_EQ(1, difference_estimator.Measure(base, subject));
EXPECT_EQ(1U, difference_estimator.Measure(base, subject));
}
2 changes: 1 addition & 1 deletion courgette/encode_decode_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void EncodeDecodeTest::TestExe(const char* file_name) const {
const void* buffer = sink.Buffer();
size_t length = sink.Length();

EXPECT_EQ(971850, length);
EXPECT_EQ(971850U, length);

courgette::SourceStreamSet sources;
bool can_get_source_streams = sources.Init(buffer, length);
Expand Down
46 changes: 19 additions & 27 deletions courgette/encoded_program.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,6 @@ const int kStreamOriginAddresses = kStreamMisc;

const int kStreamLimit = 9;

// Binary assembly language operations.
enum EncodedProgram::OP {
ORIGIN, // ORIGIN <rva> - set address for subsequent assembly.
COPY, // COPY <count> <bytes> - copy bytes to output.
COPY1, // COPY1 <byte> - same as COPY 1 <byte>.
REL32, // REL32 <index> - emit rel32 encoded reference to address at
// address table offset <index>
ABS32, // ABS32 <index> - emit abs32 encoded reference to address at
// address table offset <index>
MAKE_BASE_RELOCATION_TABLE, // Emit base relocation table blocks.
OP_LAST
};


// Constructor is here rather than in the header. Although the constructor
// appears to do nothing it is fact quite large because of the implict calls to
// field constructors. Ditto for the destructor.
Expand Down Expand Up @@ -499,32 +485,38 @@ bool EncodedProgram::AssembleTo(SinkStream* final_buffer) {
// RelocBlock has the layout of a block of relocations in the base relocation
// table file format.
//
class RelocBlock {
public:
struct RelocBlockPOD {
uint32 page_rva;
uint32 block_size;
uint16 relocs[4096]; // Allow up to one relocation per byte of a 4k page.
};

RelocBlock() : page_rva(~0), block_size(8) {}
COMPILE_ASSERT(offsetof(RelocBlockPOD, relocs) == 8, reloc_block_header_size);

class RelocBlock {
public:
RelocBlock() {
pod.page_rva = ~0;
pod.block_size = 8;
}

void Add(uint16 item) {
relocs[(block_size-8)/2] = item;
block_size += 2;
pod.relocs[(pod.block_size-8)/2] = item;
pod.block_size += 2;
}

void Flush(SinkStream* buffer) {
if (block_size != 8) {
if (block_size % 4 != 0) { // Pad to make size multiple of 4 bytes.
if (pod.block_size != 8) {
if (pod.block_size % 4 != 0) { // Pad to make size multiple of 4 bytes.
Add(0);
}
buffer->Write(this, block_size);
block_size = 8;
buffer->Write(&pod, pod.block_size);
pod.block_size = 8;
}
}
RelocBlockPOD pod;
};

COMPILE_ASSERT(offsetof(RelocBlock, relocs) == 8, reloc_block_header_size);

void EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) {
std::sort(abs32_relocs_.begin(), abs32_relocs_.end());

Expand All @@ -533,9 +525,9 @@ void EncodedProgram::GenerateBaseRelocations(SinkStream* buffer) {
for (size_t i = 0; i < abs32_relocs_.size(); ++i) {
uint32 rva = abs32_relocs_[i];
uint32 page_rva = rva & ~0xFFF;
if (page_rva != block.page_rva) {
if (page_rva != block.pod.page_rva) {
block.Flush(buffer);
block.page_rva = page_rva;
block.pod.page_rva = page_rva;
}
block.Add(0x3000 | (rva & 0xFFF));
}
Expand Down
15 changes: 13 additions & 2 deletions courgette/encoded_program.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,18 @@ class EncodedProgram {
bool AssembleTo(SinkStream *buffer);

private:
enum OP; // Binary assembly language operations.
// Binary assembly language operations.
enum OP {
ORIGIN, // ORIGIN <rva> - set address for subsequent assembly.
COPY, // COPY <count> <bytes> - copy bytes to output.
COPY1, // COPY1 <byte> - same as COPY 1 <byte>.
REL32, // REL32 <index> - emit rel32 encoded reference to address at
// address table offset <index>
ABS32, // ABS32 <index> - emit abs32 encoded reference to address at
// address table offset <index>
MAKE_BASE_RELOCATION_TABLE, // Emit base relocation table blocks.
OP_LAST
};

void DebuggingSummary();
void GenerateBaseRelocations(SinkStream *buffer);
Expand All @@ -80,4 +91,4 @@ class EncodedProgram {
};

} // namespace courgette
#endif // COURGETTE_ENCODED_FORMAT_H_
#endif // COURGETTE_ENCODED_PROGRAM_H_
8 changes: 4 additions & 4 deletions courgette/encoded_program_fuzz_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ class DecodeFuzzTest : public testing::Test {
private:
virtual void SetUp() {
PathService::Get(base::DIR_SOURCE_ROOT, &testdata_dir_);
testdata_dir_ = testdata_dir_.Append(L"courgette");
testdata_dir_ = testdata_dir_.Append(L"testdata");
testdata_dir_ = testdata_dir_.AppendASCII("courgette");
testdata_dir_ = testdata_dir_.AppendASCII("testdata");
}

virtual void TearDown() { }
Expand Down Expand Up @@ -188,10 +188,10 @@ void DecodeFuzzTest::FuzzBits(const std::string& base_buffer,
}

if (index > 60) { // Beyond the origin addresses ...
EXPECT_NE(0, changed_byte_count); // ... we expect some difference.
EXPECT_NE(0U, changed_byte_count); // ... we expect some difference.
}
// Currently all changes are smaller than this number:
EXPECT_GE(45000u, changed_byte_count);
EXPECT_GE(45000U, changed_byte_count);
}
}

Expand Down
2 changes: 1 addition & 1 deletion courgette/encoded_program_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ TEST(EncodedProgramTest, Test) {
const void* assembled_buffer = assembled.Buffer();
size_t assembled_length = assembled.Length();

EXPECT_EQ(8, assembled_length);
EXPECT_EQ(8U, assembled_length);

static const uint8 golden[] = {
0x04, 0x00, 0x90, 0x00, // ABS32 to base + 4
Expand Down
Loading

0 comments on commit 54f1b82

Please sign in to comment.