test_assembler_unittest.cc revision 073a7f6695bd16937eb0345459de2ad10c4e0cd2
1// Copyright (c) 2010, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8//     * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10//     * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14//     * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30// Original author: Jim Blandy <jimb@mozilla.com> <jimb@red-bean.com>
31
32// test_assembler_unittest.cc: Unit tests for google_breakpad::TestAssembler.
33
34#include <string>
35#include <string.h>
36
37#include "breakpad_googletest_includes.h"
38#include "common/test_assembler.h"
39
40using google_breakpad::TestAssembler::Label;
41using google_breakpad::TestAssembler::Section;
42using google_breakpad::TestAssembler::kBigEndian;
43using google_breakpad::TestAssembler::kLittleEndian;
44using std::string;
45using testing::Test;
46
47TEST(ConstructLabel, Simple) {
48  Label l;
49}
50
51TEST(ConstructLabel, Undefined) {
52  Label l;
53  EXPECT_FALSE(l.IsKnownConstant());
54}
55
56TEST(ConstructLabelDeathTest, Undefined) {
57  Label l;
58  ASSERT_DEATH(l.Value(), "IsKnownConstant\\(&v\\)");
59}
60
61TEST(ConstructLabel, Constant) {
62  Label l(0x060b9f974eaf301eULL);
63  u_int64_t v;
64  EXPECT_TRUE(l.IsKnownConstant(&v));
65  EXPECT_EQ(v, 0x060b9f974eaf301eULL);
66  EXPECT_EQ(l.Value(), 0x060b9f974eaf301eULL);
67}
68
69TEST(ConstructLabel, Copy) {
70  Label l;
71  Label m(l);
72  u_int64_t v;
73  EXPECT_TRUE(l.IsKnownOffsetFrom(m, &v));
74  EXPECT_EQ(0U, v);
75}
76
77// The left-hand-side of a label assignment can be either
78// unconstrained, related, or known. The right-hand-side can be any of
79// those, or an integer.
80TEST(Assignment, UnconstrainedToUnconstrained) {
81  Label l, m;
82  l = m;
83  EXPECT_EQ(0U, l-m);
84  EXPECT_TRUE(l.IsKnownOffsetFrom(m));
85  u_int64_t d;
86  EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d));
87  EXPECT_EQ(0U, d);
88  EXPECT_FALSE(l.IsKnownConstant());
89}
90
91TEST(Assignment, UnconstrainedToRelated) {
92  Label l, m, n;
93  l = n;
94  l = m;
95  EXPECT_EQ(0U, l-m);
96  EXPECT_TRUE(l.IsKnownOffsetFrom(m));
97  u_int64_t d;
98  EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d));
99  EXPECT_EQ(0U, d);
100  EXPECT_FALSE(l.IsKnownConstant());
101}
102
103TEST(Assignment, UnconstrainedToKnown) {
104  Label l, m;
105  l = 0x8fd16e55b20a39c1ULL;
106  l = m;
107  EXPECT_EQ(0U, l-m);
108  EXPECT_TRUE(l.IsKnownOffsetFrom(m));
109  u_int64_t d;
110  EXPECT_TRUE(l.IsKnownOffsetFrom(m, &d));
111  EXPECT_EQ(0U, d);
112  EXPECT_TRUE(m.IsKnownConstant());
113  EXPECT_EQ(0x8fd16e55b20a39c1ULL, m.Value());
114}
115
116TEST(Assignment, RelatedToUnconstrained) {
117  Label l, m, n;
118  m = n;
119  l = m;
120  EXPECT_EQ(0U, l-n);
121  EXPECT_TRUE(l.IsKnownOffsetFrom(n));
122  u_int64_t d;
123  EXPECT_TRUE(l.IsKnownOffsetFrom(n, &d));
124  EXPECT_EQ(0U, d);
125  EXPECT_FALSE(l.IsKnownConstant());
126}
127
128TEST(Assignment, RelatedToRelated) {
129  Label l, m, n, o;
130  l = n;
131  m = o;
132  l = m;
133  EXPECT_EQ(0U, n-o);
134  EXPECT_TRUE(n.IsKnownOffsetFrom(o));
135  u_int64_t d;
136  EXPECT_TRUE(n.IsKnownOffsetFrom(o, &d));
137  EXPECT_EQ(0U, d);
138  EXPECT_FALSE(l.IsKnownConstant());
139}
140
141TEST(Assignment, RelatedToKnown) {
142  Label l, m, n;
143  m = n;
144  l = 0xd2011f8c82ad56f2ULL;
145  l = m;
146  EXPECT_TRUE(l.IsKnownConstant());
147  EXPECT_EQ(0xd2011f8c82ad56f2ULL, l.Value());
148  EXPECT_TRUE(m.IsKnownConstant());
149  EXPECT_EQ(0xd2011f8c82ad56f2ULL, m.Value());
150  EXPECT_TRUE(n.IsKnownConstant());
151  EXPECT_EQ(0xd2011f8c82ad56f2ULL, n.Value());
152}
153
154TEST(Assignment, KnownToUnconstrained) {
155  Label l, m;
156  m = 0x50b024c0d6073887ULL;
157  l = m;
158  EXPECT_TRUE(l.IsKnownConstant());
159  EXPECT_EQ(0x50b024c0d6073887ULL, l.Value());
160  EXPECT_TRUE(m.IsKnownConstant());
161  EXPECT_EQ(0x50b024c0d6073887ULL, m.Value());
162}
163
164TEST(Assignment, KnownToRelated) {
165  Label l, m, n;
166  l = n;
167  m = 0x5348883655c727e5ULL;
168  l = m;
169  EXPECT_TRUE(l.IsKnownConstant());
170  EXPECT_EQ(0x5348883655c727e5ULL, l.Value());
171  EXPECT_TRUE(m.IsKnownConstant());
172  EXPECT_EQ(0x5348883655c727e5ULL, m.Value());
173  EXPECT_TRUE(n.IsKnownConstant());
174  EXPECT_EQ(0x5348883655c727e5ULL, n.Value());
175}
176
177TEST(Assignment, KnownToKnown) {
178  Label l, m;
179  l = 0x36c209c20987564eULL;
180  m = 0x36c209c20987564eULL;
181  l = m;
182  EXPECT_TRUE(l.IsKnownConstant());
183  EXPECT_EQ(0x36c209c20987564eULL, l.Value());
184  EXPECT_TRUE(m.IsKnownConstant());
185  EXPECT_EQ(0x36c209c20987564eULL, m.Value());
186}
187
188TEST(Assignment, ConstantToUnconstrained) {
189  Label l;
190  l = 0xc02495f4d7f5a957ULL;
191  EXPECT_TRUE(l.IsKnownConstant());
192  EXPECT_EQ(0xc02495f4d7f5a957ULL, l.Value());
193}
194
195TEST(Assignment, ConstantToRelated) {
196  Label l, m;
197  l = m;
198  l = 0x4577901cf275488dULL;
199  EXPECT_TRUE(l.IsKnownConstant());
200  EXPECT_EQ(0x4577901cf275488dULL, l.Value());
201  EXPECT_TRUE(m.IsKnownConstant());
202  EXPECT_EQ(0x4577901cf275488dULL, m.Value());
203}
204
205TEST(Assignment, ConstantToKnown) {
206  Label l;
207  l = 0xec0b9c369b7e8ea7ULL;
208  l = 0xec0b9c369b7e8ea7ULL;
209  EXPECT_TRUE(l.IsKnownConstant());
210  EXPECT_EQ(0xec0b9c369b7e8ea7ULL, l.Value());
211}
212
213TEST(AssignmentDeathTest, Self) {
214  Label l;
215  ASSERT_DEATH(l = l, "binding != this");
216}
217
218TEST(AssignmentDeathTest, IndirectCycle) {
219  Label l, m, n;
220  l = m;
221  m = n;
222  ASSERT_DEATH(n = l, "binding != this");
223}
224
225TEST(AssignmentDeathTest, Cycle) {
226  Label l, m, n, o;
227  l = m;
228  m = n;
229  o = n;
230  ASSERT_DEATH(o = l, "binding != this");
231}
232
233TEST(Addition, LabelConstant) {
234  Label l, m;
235  m = l + 0x5248d93e8bbe9497ULL;
236  EXPECT_TRUE(m.IsKnownOffsetFrom(l));
237  u_int64_t d;
238  EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
239  EXPECT_EQ(0x5248d93e8bbe9497ULL, d);
240  EXPECT_FALSE(m.IsKnownConstant());
241}
242
243TEST(Addition, ConstantLabel) {
244  Label l, m;
245  m = 0xf51e94e00d6e3c84ULL + l;
246  EXPECT_TRUE(m.IsKnownOffsetFrom(l));
247  u_int64_t d;
248  EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
249  EXPECT_EQ(0xf51e94e00d6e3c84ULL, d);
250  EXPECT_FALSE(m.IsKnownConstant());
251}
252
253TEST(Addition, KnownLabelConstant) {
254  Label l, m;
255  l = 0x16286307042ce0d8ULL;
256  m = l + 0x3fdddd91306719d7ULL;
257  EXPECT_TRUE(m.IsKnownOffsetFrom(l));
258  u_int64_t d;
259  EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
260  EXPECT_EQ(0x3fdddd91306719d7ULL, d);
261  EXPECT_TRUE(m.IsKnownConstant());
262  EXPECT_EQ(0x16286307042ce0d8ULL + 0x3fdddd91306719d7ULL, m.Value());
263}
264
265TEST(Addition, ConstantKnownLabel) {
266  Label l, m;
267  l = 0x50f62d0cdd1031deULL;
268  m = 0x1b13462d8577c538ULL + l;
269  EXPECT_TRUE(m.IsKnownOffsetFrom(l));
270  u_int64_t d;
271  EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
272  EXPECT_EQ(0x1b13462d8577c538ULL, d);
273  EXPECT_TRUE(m.IsKnownConstant());
274  EXPECT_EQ(0x50f62d0cdd1031deULL + 0x1b13462d8577c538ULL, m.Value());
275}
276
277TEST(Subtraction, LabelConstant) {
278  Label l, m;
279  m = l - 0x0620884d21d3138eULL;
280  EXPECT_TRUE(m.IsKnownOffsetFrom(l));
281  u_int64_t d;
282  EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
283  EXPECT_EQ(-0x0620884d21d3138eULL, d);
284  EXPECT_FALSE(m.IsKnownConstant());
285}
286
287TEST(Subtraction, KnownLabelConstant) {
288  Label l, m;
289  l = 0x6237fbaf9ef7929eULL;
290  m = l - 0x317730995d2ab6eeULL;
291  EXPECT_TRUE(m.IsKnownOffsetFrom(l));
292  u_int64_t d;
293  EXPECT_TRUE(m.IsKnownOffsetFrom(l, &d));
294  EXPECT_EQ(-0x317730995d2ab6eeULL, d);
295  EXPECT_TRUE(m.IsKnownConstant());
296  EXPECT_EQ(0x6237fbaf9ef7929eULL - 0x317730995d2ab6eeULL, m.Value());
297}
298
299TEST(SubtractionDeathTest, LabelLabel) {
300  Label l, m;
301  ASSERT_DEATH(l - m, "IsKnownOffsetFrom\\(label, &offset\\)");
302}
303
304TEST(Subtraction, LabelLabel) {
305  Label l, m;
306  l = m + 0x7fa77ec63e28a17aULL;
307  EXPECT_EQ(0x7fa77ec63e28a17aULL, l - m);
308  EXPECT_EQ(-0x7fa77ec63e28a17aULL, m - l);
309}
310
311TEST(IsKnownConstant, Undefined) {
312  Label l;
313  EXPECT_FALSE(l.IsKnownConstant());
314}
315
316TEST(IsKnownConstant, RelatedLabel) {
317  Label l, m;
318  l = m;
319  EXPECT_FALSE(l.IsKnownConstant());
320  EXPECT_FALSE(m.IsKnownConstant());
321}
322
323TEST(IsKnownConstant, Constant) {
324  Label l;
325  l = 0xf374b1bdd6a22576ULL;
326  EXPECT_TRUE(l.IsKnownConstant());
327}
328
329TEST(IsKnownOffsetFrom, Unrelated) {
330  Label l, m;
331  EXPECT_FALSE(l.IsKnownOffsetFrom(m));
332}
333
334TEST(IsKnownOffsetFrom, Related) {
335  Label l, m;
336  l = m;
337  EXPECT_TRUE(l.IsKnownOffsetFrom(m));
338}
339
340// Test the construction of chains of related labels, and the
341// propagation of values through them.
342//
343// Although the relations between labels are supposed to behave
344// symmetrically --- that is, 'a = b' should put a and b in
345// indistinguishable states --- there's a distinction made internally
346// between the target (a) and the source (b).
347//
348// So there are five test axes to cover:
349//
350// - Do we construct the chain with assignment ("Assign") or with constructors
351//   ("Construct")?
352//
353// - Do we set the value of the label at the start of the chain
354//   ("Start") or the label at the end ("End")?
355//
356// - Are we testing the propagation of a relationship between variable
357//   values ("Relation"), or the propagation of a known constant value
358//   ("Value")?
359//
360// - Do we set the value before building the chain ("Before") or after
361//   the chain has been built ("After")?
362//
363// - Do we add new relationships to the end of the existing chain
364//   ("Forward") or to the beginning ("Backward")?
365//
366// Of course, "Construct" and "Backward" can't be combined, which
367// eliminates eight combinations, and "Construct", "End", and "Before"
368// can't be combined, which eliminates two more, so there are are 22
369// combinations, not 32.
370
371TEST(LabelChain, AssignStartRelationBeforeForward) {
372  Label a, b, c, d;
373  Label x;
374  a = x;
375  b = a + 0x1;
376  c = b + 0x10;
377  d = c + 0x100;
378  EXPECT_EQ(0x111U, d-x);
379  EXPECT_EQ(0x11U,  c-x);
380  EXPECT_EQ(0x1U,   b-x);
381  EXPECT_EQ(0U,     a-x);
382}
383
384TEST(LabelChain, AssignStartRelationBeforeBackward) {
385  Label a, b, c, d;
386  Label x;
387  a = x;
388  d = c + 0x100;
389  c = b + 0x10;
390  b = a + 0x1;
391  EXPECT_EQ(0x111U, d-x);
392  EXPECT_EQ(0x11U,  c-x);
393  EXPECT_EQ(0x1U,   b-x);
394  EXPECT_EQ(0U,     a-x);
395}
396
397TEST(LabelChain, AssignStartRelationAfterForward) {
398  Label a, b, c, d;
399  Label x;
400  b = a + 0x1;
401  c = b + 0x10;
402  d = c + 0x100;
403  a = x;
404  EXPECT_EQ(0x111U, d-x);
405  EXPECT_EQ(0x11U,  c-x);
406  EXPECT_EQ(0x1U,   b-x);
407  EXPECT_EQ(0U,     a-x);
408}
409
410TEST(LabelChain, AssignStartRelationAfterBackward) {
411  Label a, b, c, d;
412  Label x;
413  d = c + 0x100;
414  c = b + 0x10;
415  b = a + 0x1;
416  a = x;
417  EXPECT_EQ(0x111U, d-x);
418  EXPECT_EQ(0x11U,  c-x);
419  EXPECT_EQ(0x1U,   b-x);
420  EXPECT_EQ(0U,     a-x);
421}
422
423TEST(LabelChain, AssignStartValueBeforeForward) {
424  Label a, b, c, d;
425  a = 0xa131200190546ac2ULL;
426  b = a + 0x1;
427  c = b + 0x10;
428  d = c + 0x100;
429  EXPECT_EQ(0xa131200190546ac2ULL + 0x111U, d.Value());
430  EXPECT_EQ(0xa131200190546ac2ULL + 0x11U,  c.Value());
431  EXPECT_EQ(0xa131200190546ac2ULL + 0x1U,   b.Value());
432  EXPECT_EQ(0xa131200190546ac2ULL + 0U,     a.Value());
433}
434
435TEST(LabelChain, AssignStartValueBeforeBackward) {
436  Label a, b, c, d;
437  a = 0x8da17e1670ad4fa2ULL;
438  d = c + 0x100;
439  c = b + 0x10;
440  b = a + 0x1;
441  EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0x111U, d.Value());
442  EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0x11U,  c.Value());
443  EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0x1U,   b.Value());
444  EXPECT_EQ(0x8da17e1670ad4fa2ULL + 0U,     a.Value());
445}
446
447TEST(LabelChain, AssignStartValueAfterForward) {
448  Label a, b, c, d;
449  b = a + 0x1;
450  c = b + 0x10;
451  d = c + 0x100;
452  a = 0x99b8f51bafd41adaULL;
453  EXPECT_EQ(0x99b8f51bafd41adaULL + 0x111U, d.Value());
454  EXPECT_EQ(0x99b8f51bafd41adaULL + 0x11U,  c.Value());
455  EXPECT_EQ(0x99b8f51bafd41adaULL + 0x1U,   b.Value());
456  EXPECT_EQ(0x99b8f51bafd41adaULL + 0U,     a.Value());
457}
458
459TEST(LabelChain, AssignStartValueAfterBackward) {
460  Label a, b, c, d;
461  d = c + 0x100;
462  c = b + 0x10;
463  b = a + 0x1;
464  a = 0xc86ca1d97ab5df6eULL;
465  EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0x111U, d.Value());
466  EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0x11U,  c.Value());
467  EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0x1U,   b.Value());
468  EXPECT_EQ(0xc86ca1d97ab5df6eULL + 0U,     a.Value());
469}
470
471TEST(LabelChain, AssignEndRelationBeforeForward) {
472  Label a, b, c, d;
473  Label x;
474  x = d;
475  b = a + 0x1;
476  c = b + 0x10;
477  d = c + 0x100;
478  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
479  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
480  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
481  EXPECT_EQ(-(u_int64_t)0U,     d-x);
482}
483
484TEST(LabelChain, AssignEndRelationBeforeBackward) {
485  Label a, b, c, d;
486  Label x;
487  x = d;
488  d = c + 0x100;
489  c = b + 0x10;
490  b = a + 0x1;
491  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
492  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
493  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
494  EXPECT_EQ(-(u_int64_t)0U,     d-x);
495}
496
497TEST(LabelChain, AssignEndRelationAfterForward) {
498  Label a, b, c, d;
499  Label x;
500  b = a + 0x1;
501  c = b + 0x10;
502  d = c + 0x100;
503  x = d;
504  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
505  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
506  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
507  EXPECT_EQ(-(u_int64_t)0x000U, d-x);
508}
509
510TEST(LabelChain, AssignEndRelationAfterBackward) {
511  Label a, b, c, d;
512  Label x;
513  d = c + 0x100;
514  c = b + 0x10;
515  b = a + 0x1;
516  x = d;
517  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
518  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
519  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
520  EXPECT_EQ(-(u_int64_t)0x000U, d-x);
521}
522
523TEST(LabelChain, AssignEndValueBeforeForward) {
524  Label a, b, c, d;
525  d = 0xa131200190546ac2ULL;
526  b = a + 0x1;
527  c = b + 0x10;
528  d = c + 0x100;
529  EXPECT_EQ(0xa131200190546ac2ULL - 0x111, a.Value());
530  EXPECT_EQ(0xa131200190546ac2ULL - 0x110, b.Value());
531  EXPECT_EQ(0xa131200190546ac2ULL - 0x100, c.Value());
532  EXPECT_EQ(0xa131200190546ac2ULL - 0x000, d.Value());
533}
534
535TEST(LabelChain, AssignEndValueBeforeBackward) {
536  Label a, b, c, d;
537  d = 0x8da17e1670ad4fa2ULL;
538  d = c + 0x100;
539  c = b + 0x10;
540  b = a + 0x1;
541  EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x111, a.Value());
542  EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x110, b.Value());
543  EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x100, c.Value());
544  EXPECT_EQ(0x8da17e1670ad4fa2ULL - 0x000, d.Value());
545}
546
547TEST(LabelChain, AssignEndValueAfterForward) {
548  Label a, b, c, d;
549  b = a + 0x1;
550  c = b + 0x10;
551  d = c + 0x100;
552  d = 0x99b8f51bafd41adaULL;
553  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x111, a.Value());
554  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x110, b.Value());
555  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x100, c.Value());
556  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x000, d.Value());
557}
558
559TEST(LabelChain, AssignEndValueAfterBackward) {
560  Label a, b, c, d;
561  d = c + 0x100;
562  c = b + 0x10;
563  b = a + 0x1;
564  d = 0xc86ca1d97ab5df6eULL;
565  EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x111, a.Value());
566  EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x110, b.Value());
567  EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x100, c.Value());
568  EXPECT_EQ(0xc86ca1d97ab5df6eULL - 0x000, d.Value());
569}
570
571TEST(LabelChain, ConstructStartRelationBeforeForward) {
572  Label x;
573  Label a(x);
574  Label b(a + 0x1);
575  Label c(b + 0x10);
576  Label d(c + 0x100);
577  EXPECT_EQ(0x111U, d-x);
578  EXPECT_EQ(0x11U,  c-x);
579  EXPECT_EQ(0x1U,   b-x);
580  EXPECT_EQ(0U,     a-x);
581}
582
583TEST(LabelChain, ConstructStartRelationAfterForward) {
584  Label x;
585  Label a;
586  Label b(a + 0x1);
587  Label c(b + 0x10);
588  Label d(c + 0x100);
589  a = x;
590  EXPECT_EQ(0x111U, d-x);
591  EXPECT_EQ(0x11U,  c-x);
592  EXPECT_EQ(0x1U,   b-x);
593  EXPECT_EQ(0U,     a-x);
594}
595
596TEST(LabelChain, ConstructStartValueBeforeForward) {
597  Label a(0x5d234d177d01ccc8ULL);
598  Label b(a + 0x1);
599  Label c(b + 0x10);
600  Label d(c + 0x100);
601  EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x111U, d.Value());
602  EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x011U, c.Value());
603  EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x001U, b.Value());
604  EXPECT_EQ(0x5d234d177d01ccc8ULL + 0x000U, a.Value());
605}
606
607TEST(LabelChain, ConstructStartValueAfterForward) {
608  Label a;
609  Label b(a + 0x1);
610  Label c(b + 0x10);
611  Label d(c + 0x100);
612  a = 0xded85d54586e84fcULL;
613  EXPECT_EQ(0xded85d54586e84fcULL + 0x111U, d.Value());
614  EXPECT_EQ(0xded85d54586e84fcULL + 0x011U, c.Value());
615  EXPECT_EQ(0xded85d54586e84fcULL + 0x001U, b.Value());
616  EXPECT_EQ(0xded85d54586e84fcULL + 0x000U, a.Value());
617}
618
619TEST(LabelChain, ConstructEndRelationAfterForward) {
620  Label x;
621  Label a;
622  Label b(a + 0x1);
623  Label c(b + 0x10);
624  Label d(c + 0x100);
625  x = d;
626  EXPECT_EQ(-(u_int64_t)0x111U, a-x);
627  EXPECT_EQ(-(u_int64_t)0x110U, b-x);
628  EXPECT_EQ(-(u_int64_t)0x100U, c-x);
629  EXPECT_EQ(-(u_int64_t)0x000U, d-x);
630}
631
632TEST(LabelChain, ConstructEndValueAfterForward) {
633  Label a;
634  Label b(a + 0x1);
635  Label c(b + 0x10);
636  Label d(c + 0x100);
637  d = 0x99b8f51bafd41adaULL;
638  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x111, a.Value());
639  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x110, b.Value());
640  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x100, c.Value());
641  EXPECT_EQ(0x99b8f51bafd41adaULL - 0x000, d.Value());
642}
643
644TEST(LabelTree, KnownValue) {
645  Label l, m, n, o, p;
646  l = m;
647  m = n;
648  o = p;
649  p = n;
650  l = 0x536b5de3d468a1b5ULL;
651  EXPECT_EQ(0x536b5de3d468a1b5ULL, o.Value());
652}
653
654TEST(LabelTree, Related) {
655  Label l, m, n, o, p;
656  l = m - 1;
657  m = n - 10;
658  o = p + 100;
659  p = n + 1000;
660  EXPECT_EQ(1111U, o - l);
661}
662
663TEST(EquationDeathTest, EqualConstants) {
664  Label m = 0x0d3962f280f07d24ULL;
665  Label n = 0x0d3962f280f07d24ULL;
666  m = n; // no death expected
667}
668
669TEST(EquationDeathTest, EqualIndirectConstants) {
670  Label m = 0xa347f1e5238fe6a1ULL;
671  Label n;
672  Label o = n;
673  n = 0xa347f1e5238fe6a1ULL;
674  n = m; // no death expected
675}
676
677TEST(EquationDeathTest, ConstantClash) {
678  Label m = 0xd4cc0f4f630ec741ULL;
679  Label n = 0x934cd2d8254fc3eaULL;
680  ASSERT_DEATH(m = n, "addend_ == addend");
681}
682
683TEST(EquationDeathTest, IndirectConstantClash) {
684  Label m = 0xd4cc0f4f630ec741ULL;
685  Label n, o;
686  n = o;
687  o = 0xcfbe3b83ac49ce86ULL;
688  ASSERT_DEATH(m = n, "addend_ == addend");
689}
690
691// Assigning to a related label may free the next Binding on its
692// chain. This test always passes; it is interesting to memory
693// checkers and coverage analysis.
694TEST(LabelReferenceCount, AssignmentFree) {
695  Label l;
696  {
697    Label m;
698    l = m;
699  }
700  // This should free m's Binding.
701  l = 0xca8bae92f0376d4fULL;
702  ASSERT_EQ(0xca8bae92f0376d4fULL, l.Value());
703}
704
705// Finding the value of a label may free the Binding it refers to. This test
706// always passes; it is interesting to memory checkers and coverage analysis.
707TEST(LabelReferenceCount, FindValueFree) {
708  Label l;
709  {
710    Label m, n;
711    l = m;
712    m = n;
713    n = 0x7a0b0c576672daafULL;
714    // At this point, l's Binding refers to m's Binding, which refers
715    // to n's binding.
716  }
717  // Now, l is the only reference keeping the three Bindings alive.
718  // Resolving its value should free l's and m's original bindings.
719  ASSERT_EQ(0x7a0b0c576672daafULL, l.Value());
720}
721
722TEST(ConstructSection, Simple) {
723  Section s;
724}
725
726TEST(ConstructSection, WithEndian) {
727  Section s(kBigEndian);
728}
729
730// A fixture class for TestAssembler::Section tests.
731class SectionFixture {
732 public:
733  Section section;
734  string contents;
735  static const u_int8_t data[];
736  static const size_t data_size;
737};
738
739const u_int8_t SectionFixture::data[] = {
740  0x87, 0x4f, 0x43, 0x67, 0x30, 0xd0, 0xd4, 0x0e
741};
742
743#define I0()
744#define I1(a) { a }
745#define I2(a,b) { a,b }
746#define I3(a,b,c) { a,b,c }
747#define I4(a,b,c,d) { a,b,c,d }
748#define I5(a,b,c,d,e) { a,b,c,d,e }
749#define I6(a,b,c,d,e,f) { a,b,c,d,e,f }
750#define I7(a,b,c,d,e,f,g) { a,b,c,d,e,f,g }
751#define I8(a,b,c,d,e,f,g,h) { a,b,c,d,e,f,g,h }
752#define I9(a,b,c,d,e,f,g,h,i) { a,b,c,d,e,f,g,h,i }
753#define ASSERT_BYTES(s, b)                                              \
754  do                                                                    \
755    {                                                                   \
756      static const u_int8_t expected_bytes[] = b;                       \
757      ASSERT_EQ(sizeof(expected_bytes), s.size());                      \
758      ASSERT_TRUE(memcmp(s.data(), (const char *) expected_bytes,       \
759                         sizeof(expected_bytes)) == 0);                 \
760    }                                                                   \
761  while(0)
762
763class Append: public SectionFixture, public Test { };
764
765TEST_F(Append, Bytes) {
766  section.Append(data, sizeof(data));
767  ASSERT_TRUE(section.GetContents(&contents));
768  ASSERT_EQ(sizeof(data), contents.size());
769  EXPECT_TRUE(0 == memcmp(contents.data(), (const char *) data, sizeof(data)));
770}
771
772TEST_F(Append, BytesTwice) {
773  section.Append(data, sizeof(data));
774  section.Append(data, sizeof(data));
775  ASSERT_TRUE(section.GetContents(&contents));
776  ASSERT_EQ(2 * sizeof(data), contents.size());
777  ASSERT_TRUE(0 == memcmp(contents.data(), (const char *) data, sizeof(data)));
778  ASSERT_TRUE(0 == memcmp(contents.data() + sizeof(data),
779                          (const char *) data, sizeof(data)));
780}
781
782TEST_F(Append, String) {
783  string s1 = "howdy ";
784  string s2 = "there";
785  section.Append(s1);
786  section.Append(s2);
787  ASSERT_TRUE(section.GetContents(&contents));
788  ASSERT_STREQ(contents.c_str(), "howdy there");
789}
790
791TEST_F(Append, CString) {
792  section.AppendCString("howdy");
793  section.AppendCString("");
794  section.AppendCString("there");
795  ASSERT_TRUE(section.GetContents(&contents));
796  ASSERT_EQ(string("howdy\0\0there\0", 13), contents);
797}
798
799TEST_F(Append, CStringSize) {
800  section.AppendCString("howdy", 3);
801  section.AppendCString("there", 5);
802  section.AppendCString("fred", 6);
803  section.AppendCString("natalie", 0);
804  section.AppendCString("", 10);
805  ASSERT_TRUE(section.GetContents(&contents));
806  ASSERT_EQ(string("howtherefred\0\0\0\0\0\0\0\0\0\0\0\0", 24), contents);
807}
808
809TEST_F(Append, RepeatedBytes) {
810  section.Append((size_t) 10, '*');
811  ASSERT_TRUE(section.GetContents(&contents));
812  ASSERT_STREQ(contents.c_str(), "**********");
813}
814
815TEST_F(Append, GeneralLE1) {
816  section.Append(kLittleEndian, 1, 42);
817  ASSERT_TRUE(section.GetContents(&contents));
818  ASSERT_BYTES(contents, I1(42));
819}
820
821TEST_F(Append, GeneralLE2) {
822  section.Append(kLittleEndian, 2, 0x15a1);
823  ASSERT_TRUE(section.GetContents(&contents));
824  ASSERT_BYTES(contents, I2(0xa1, 0x15));
825}
826
827TEST_F(Append, GeneralLE3) {
828  section.Append(kLittleEndian, 3, 0x59ae8d);
829  ASSERT_TRUE(section.GetContents(&contents));
830  ASSERT_BYTES(contents, I3(0x8d, 0xae, 0x59));
831}
832
833TEST_F(Append, GeneralLE4) {
834  section.Append(kLittleEndian, 4, 0x51603c56);
835  ASSERT_TRUE(section.GetContents(&contents));
836  ASSERT_BYTES(contents, I4(0x56, 0x3c, 0x60, 0x51));
837}
838
839TEST_F(Append, GeneralLE5) {
840  section.Append(kLittleEndian, 5, 0x385e2803b4ULL);
841  ASSERT_TRUE(section.GetContents(&contents));
842  ASSERT_BYTES(contents, I5(0xb4, 0x03, 0x28, 0x5e, 0x38));
843}
844
845TEST_F(Append, GeneralLE6) {
846  section.Append(kLittleEndian, 6, 0xc7db9534dd1fULL);
847  ASSERT_TRUE(section.GetContents(&contents));
848  ASSERT_BYTES(contents, I6(0x1f, 0xdd, 0x34, 0x95, 0xdb, 0xc7));
849}
850
851TEST_F(Append, GeneralLE7) {
852  section.Append(kLittleEndian, 7, 0x1445c9f1b843e6ULL);
853  ASSERT_TRUE(section.GetContents(&contents));
854  ASSERT_BYTES(contents, I7(0xe6, 0x43, 0xb8, 0xf1, 0xc9, 0x45, 0x14));
855}
856
857TEST_F(Append, GeneralLE8) {
858  section.Append(kLittleEndian, 8, 0xaf48019dfe5c01e5ULL);
859  ASSERT_TRUE(section.GetContents(&contents));
860  ASSERT_BYTES(contents, I8(0xe5, 0x01, 0x5c, 0xfe, 0x9d, 0x01, 0x48, 0xaf));
861}
862
863TEST_F(Append, GeneralBE1) {
864  section.Append(kBigEndian, 1, 0xd0ULL);
865  ASSERT_TRUE(section.GetContents(&contents));
866  ASSERT_BYTES(contents, I1(0xd0));
867}
868
869TEST_F(Append, GeneralBE2) {
870  section.Append(kBigEndian, 2, 0x2e7eULL);
871  ASSERT_TRUE(section.GetContents(&contents));
872  ASSERT_BYTES(contents, I2(0x2e, 0x7e));
873}
874
875TEST_F(Append, GeneralBE3) {
876  section.Append(kBigEndian, 3, 0x37dad6ULL);
877  ASSERT_TRUE(section.GetContents(&contents));
878  ASSERT_BYTES(contents, I3(0x37, 0xda, 0xd6));
879}
880
881TEST_F(Append, GeneralBE4) {
882  section.Append(kBigEndian, 4, 0x715935c7ULL);
883  ASSERT_TRUE(section.GetContents(&contents));
884  ASSERT_BYTES(contents, I4(0x71, 0x59, 0x35, 0xc7));
885}
886
887TEST_F(Append, GeneralBE5) {
888  section.Append(kBigEndian, 5, 0x42baeb02b7ULL);
889  ASSERT_TRUE(section.GetContents(&contents));
890  ASSERT_BYTES(contents, I5(0x42, 0xba, 0xeb, 0x02, 0xb7));
891}
892
893TEST_F(Append, GeneralBE6) {
894  section.Append(kBigEndian, 6, 0xf1cdf10e7b18ULL);
895  ASSERT_TRUE(section.GetContents(&contents));
896  ASSERT_BYTES(contents, I6(0xf1, 0xcd, 0xf1, 0x0e, 0x7b, 0x18));
897}
898
899TEST_F(Append, GeneralBE7) {
900  section.Append(kBigEndian, 7, 0xf50a724f0b0d20ULL);
901  ASSERT_TRUE(section.GetContents(&contents));
902  ASSERT_BYTES(contents, I7(0xf5, 0x0a, 0x72, 0x4f, 0x0b, 0x0d, 0x20));
903}
904
905TEST_F(Append, GeneralBE8) {
906  section.Append(kBigEndian, 8, 0xa6b2cb5e98dc9c16ULL);
907  ASSERT_TRUE(section.GetContents(&contents));
908  ASSERT_BYTES(contents, I8(0xa6, 0xb2, 0xcb, 0x5e, 0x98, 0xdc, 0x9c, 0x16));
909}
910
911TEST_F(Append, GeneralLE1Label) {
912  Label l;
913  section.Append(kLittleEndian, 1, l);
914  l = 42;
915  ASSERT_TRUE(section.GetContents(&contents));
916  ASSERT_BYTES(contents, I1(42));
917}
918
919TEST_F(Append, GeneralLE2Label) {
920  Label l;
921  section.Append(kLittleEndian, 2, l);
922  l = 0x15a1;
923  ASSERT_TRUE(section.GetContents(&contents));
924  ASSERT_BYTES(contents, I2(0xa1, 0x15));
925}
926
927TEST_F(Append, GeneralLE3Label) {
928  Label l;
929  section.Append(kLittleEndian, 3, l);
930  l = 0x59ae8d;
931  ASSERT_TRUE(section.GetContents(&contents));
932  ASSERT_BYTES(contents, I3(0x8d, 0xae, 0x59));
933}
934
935TEST_F(Append, GeneralLE4Label) {
936  Label l;
937  section.Append(kLittleEndian, 4, l);
938  l = 0x51603c56;
939  ASSERT_TRUE(section.GetContents(&contents));
940  ASSERT_BYTES(contents, I4(0x56, 0x3c, 0x60, 0x51));
941}
942
943TEST_F(Append, GeneralLE5Label) {
944  Label l;
945  section.Append(kLittleEndian, 5, l);
946  l = 0x385e2803b4ULL;
947  ASSERT_TRUE(section.GetContents(&contents));
948  ASSERT_BYTES(contents, I5(0xb4, 0x03, 0x28, 0x5e, 0x38));
949}
950
951TEST_F(Append, GeneralLE6Label) {
952  Label l;
953  section.Append(kLittleEndian, 6, l);
954  l = 0xc7db9534dd1fULL;
955  ASSERT_TRUE(section.GetContents(&contents));
956  ASSERT_BYTES(contents, I6(0x1f, 0xdd, 0x34, 0x95, 0xdb, 0xc7));
957}
958
959TEST_F(Append, GeneralLE7Label) {
960  Label l;
961  section.Append(kLittleEndian, 7, l);
962  l = 0x1445c9f1b843e6ULL;
963  ASSERT_TRUE(section.GetContents(&contents));
964  ASSERT_BYTES(contents, I7(0xe6, 0x43, 0xb8, 0xf1, 0xc9, 0x45, 0x14));
965}
966
967TEST_F(Append, GeneralLE8Label) {
968  Label l;
969  section.Append(kLittleEndian, 8, l);
970  l = 0xaf48019dfe5c01e5ULL;
971  ASSERT_TRUE(section.GetContents(&contents));
972  ASSERT_BYTES(contents, I8(0xe5, 0x01, 0x5c, 0xfe, 0x9d, 0x01, 0x48, 0xaf));
973}
974
975TEST_F(Append, GeneralBE1Label) {
976  Label l;
977  section.Append(kBigEndian, 1, l);
978  l = 0xd0ULL;
979  ASSERT_TRUE(section.GetContents(&contents));
980  ASSERT_BYTES(contents, I1(0xd0));
981}
982
983TEST_F(Append, GeneralBE2Label) {
984  Label l;
985  section.Append(kBigEndian, 2, l);
986  l = 0x2e7eULL;
987  ASSERT_TRUE(section.GetContents(&contents));
988  ASSERT_BYTES(contents, I2(0x2e, 0x7e));
989}
990
991TEST_F(Append, GeneralBE3Label) {
992  Label l;
993  section.Append(kBigEndian, 3, l);
994  l = 0x37dad6ULL;
995  ASSERT_TRUE(section.GetContents(&contents));
996  ASSERT_BYTES(contents, I3(0x37, 0xda, 0xd6));
997}
998
999TEST_F(Append, GeneralBE4Label) {
1000  Label l;
1001  section.Append(kBigEndian, 4, l);
1002  l = 0x715935c7ULL;
1003  ASSERT_TRUE(section.GetContents(&contents));
1004  ASSERT_BYTES(contents, I4(0x71, 0x59, 0x35, 0xc7));
1005}
1006
1007TEST_F(Append, GeneralBE5Label) {
1008  Label l;
1009  section.Append(kBigEndian, 5, l);
1010  l = 0x42baeb02b7ULL;
1011  ASSERT_TRUE(section.GetContents(&contents));
1012  ASSERT_BYTES(contents, I5(0x42, 0xba, 0xeb, 0x02, 0xb7));
1013}
1014
1015TEST_F(Append, GeneralBE6Label) {
1016  Label l;
1017  section.Append(kBigEndian, 6, l);
1018  l = 0xf1cdf10e7b18ULL;
1019  ASSERT_TRUE(section.GetContents(&contents));
1020  ASSERT_BYTES(contents, I6(0xf1, 0xcd, 0xf1, 0x0e, 0x7b, 0x18));
1021}
1022
1023TEST_F(Append, GeneralBE7Label) {
1024  Label l;
1025  section.Append(kBigEndian, 7, l);
1026  l = 0xf50a724f0b0d20ULL;
1027  ASSERT_TRUE(section.GetContents(&contents));
1028  ASSERT_BYTES(contents, I7(0xf5, 0x0a, 0x72, 0x4f, 0x0b, 0x0d, 0x20));
1029}
1030
1031TEST_F(Append, GeneralBE8Label) {
1032  Label l;
1033  section.Append(kBigEndian, 8, l);
1034  l = 0xa6b2cb5e98dc9c16ULL;
1035  ASSERT_TRUE(section.GetContents(&contents));
1036  ASSERT_BYTES(contents, I8(0xa6, 0xb2, 0xcb, 0x5e, 0x98, 0xdc, 0x9c, 0x16));
1037}
1038
1039TEST_F(Append, B8) {
1040  section.Append(1, 0x2a);
1041  section.B8(0xd3U);
1042  ASSERT_TRUE(section.GetContents(&contents));
1043  ASSERT_BYTES(contents, I2(0x2a, 0xd3));
1044}
1045
1046TEST_F(Append, B8Label) {
1047  Label l;
1048  section.Append(1, 0x2a);
1049  section.B8(l);
1050  l = 0x4bU;
1051  ASSERT_TRUE(section.GetContents(&contents));
1052  ASSERT_BYTES(contents, I2(0x2a, 0x4b));
1053}
1054
1055TEST_F(Append, B16) {
1056  section.Append(1, 0x2a);
1057  section.B16(0x472aU);
1058  ASSERT_TRUE(section.GetContents(&contents));
1059  ASSERT_BYTES(contents, I3(0x2a, 0x47, 0x2a));
1060}
1061
1062TEST_F(Append, B16Label) {
1063  Label l;
1064  section.Append(1, 0x2a);
1065  section.B16(l);
1066  l = 0x55e8U;
1067  ASSERT_TRUE(section.GetContents(&contents));
1068  ASSERT_BYTES(contents, I3(0x2a, 0x55, 0xe8));
1069}
1070
1071TEST_F(Append, B32) {
1072  section.Append(1, 0x2a);
1073  section.B32(0xbd412cbcU);
1074  ASSERT_TRUE(section.GetContents(&contents));
1075  ASSERT_BYTES(contents, I5(0x2a, 0xbd, 0x41, 0x2c, 0xbc));
1076}
1077
1078TEST_F(Append, B32Label) {
1079  Label l;
1080  section.Append(1, 0x2a);
1081  section.B32(l);
1082  l = 0x208e37d5U;
1083  ASSERT_TRUE(section.GetContents(&contents));
1084  ASSERT_BYTES(contents, I5(0x2a, 0x20, 0x8e, 0x37, 0xd5));
1085}
1086
1087TEST_F(Append, B64) {
1088  section.Append(1, 0x2a);
1089  section.B64(0x3402a013111e68adULL);
1090  ASSERT_TRUE(section.GetContents(&contents));
1091  ASSERT_BYTES(contents,
1092               I9(0x2a, 0x34, 0x02, 0xa0, 0x13, 0x11, 0x1e, 0x68, 0xad));
1093}
1094
1095TEST_F(Append, B64Label) {
1096  Label l;
1097  section.Append(1, 0x2a);
1098  section.B64(l);
1099  l = 0x355dbfbb4ac6d57fULL;
1100  ASSERT_TRUE(section.GetContents(&contents));
1101  ASSERT_BYTES(contents,
1102               I9(0x2a, 0x35, 0x5d, 0xbf, 0xbb, 0x4a, 0xc6, 0xd5, 0x7f));
1103}
1104
1105TEST_F(Append, L8) {
1106  section.Append(1, 0x2a);
1107  section.L8(0x26U);
1108  ASSERT_TRUE(section.GetContents(&contents));
1109  ASSERT_BYTES(contents, I2(0x2a, 0x26));
1110}
1111
1112TEST_F(Append, L8Label) {
1113  Label l;
1114  section.Append(1, 0x2a);
1115  section.L8(l);
1116  l = 0xa8U;
1117  ASSERT_TRUE(section.GetContents(&contents));
1118  ASSERT_BYTES(contents, I2(0x2a, 0xa8));
1119}
1120
1121TEST_F(Append, L16) {
1122  section.Append(1, 0x2a);
1123  section.L16(0xca6dU);
1124  ASSERT_TRUE(section.GetContents(&contents));
1125  ASSERT_BYTES(contents, I3(0x2a, 0x6d, 0xca));
1126}
1127
1128TEST_F(Append, L16Label) {
1129  Label l;
1130  section.Append(1, 0x2a);
1131  section.L16(l);
1132  l = 0xd21fU;
1133  ASSERT_TRUE(section.GetContents(&contents));
1134  ASSERT_BYTES(contents, I3(0x2a, 0x1f, 0xd2));
1135}
1136
1137TEST_F(Append, L32) {
1138  section.Append(1, 0x2a);
1139  section.L32(0x558f6181U);
1140  ASSERT_TRUE(section.GetContents(&contents));
1141  ASSERT_BYTES(contents, I5(0x2a, 0x81, 0x61, 0x8f, 0x55));
1142}
1143
1144TEST_F(Append, L32Label) {
1145  Label l;
1146  section.Append(1, 0x2a);
1147  section.L32(l);
1148  l = 0x4b810f82U;
1149  ASSERT_TRUE(section.GetContents(&contents));
1150  ASSERT_BYTES(contents, I5(0x2a, 0x82, 0x0f, 0x81, 0x4b));
1151}
1152
1153TEST_F(Append, L64) {
1154  section.Append(1, 0x2a);
1155  section.L64(0x564384f7579515bfULL);
1156  ASSERT_TRUE(section.GetContents(&contents));
1157  ASSERT_BYTES(contents,
1158               I9(0x2a, 0xbf, 0x15, 0x95, 0x57, 0xf7, 0x84, 0x43, 0x56));
1159}
1160
1161TEST_F(Append, L64Label) {
1162  Label l;
1163  section.Append(1, 0x2a);
1164  section.L64(l);
1165  l = 0x424b1d020667c8dbULL;
1166  ASSERT_TRUE(section.GetContents(&contents));
1167  ASSERT_BYTES(contents,
1168               I9(0x2a, 0xdb, 0xc8, 0x67, 0x06, 0x02, 0x1d, 0x4b, 0x42));
1169}
1170
1171TEST_F(Append, D8Big) {
1172  section.set_endianness(kBigEndian);
1173  section.Append(1, 0x2a);
1174  section.D8(0xe6U);
1175  ASSERT_TRUE(section.GetContents(&contents));
1176  ASSERT_BYTES(contents, I2(0x2a, 0xe6));
1177}
1178
1179TEST_F(Append, D8BigLabel) {
1180  Label l;
1181  section.set_endianness(kBigEndian);
1182  section.Append(1, 0x2a);
1183  section.D8(l);
1184  l = 0xeeU;
1185  ASSERT_TRUE(section.GetContents(&contents));
1186  ASSERT_BYTES(contents, I2(0x2a, 0xee));
1187}
1188
1189TEST_F(Append, D16Big) {
1190  section.set_endianness(kBigEndian);
1191  section.Append(1, 0x2a);
1192  section.D16(0x83b1U);
1193  ASSERT_TRUE(section.GetContents(&contents));
1194  ASSERT_BYTES(contents, I3(0x2a, 0x83, 0xb1));
1195}
1196
1197TEST_F(Append, D16BigLabel) {
1198  Label l;
1199  section.set_endianness(kBigEndian);
1200  section.Append(1, 0x2a);
1201  section.D16(l);
1202  l = 0x5b55U;
1203  ASSERT_TRUE(section.GetContents(&contents));
1204  ASSERT_BYTES(contents, I3(0x2a, 0x5b, 0x55));
1205}
1206
1207TEST_F(Append, D32Big) {
1208  section.set_endianness(kBigEndian);
1209  section.Append(1, 0x2a);
1210  section.D32(0xd0b0e431U);
1211  ASSERT_TRUE(section.GetContents(&contents));
1212  ASSERT_BYTES(contents, I5(0x2a, 0xd0, 0xb0, 0xe4, 0x31));
1213}
1214
1215TEST_F(Append, D32BigLabel) {
1216  Label l;
1217  section.set_endianness(kBigEndian);
1218  section.Append(1, 0x2a);
1219  section.D32(l);
1220  l = 0x312fb340U;
1221  ASSERT_TRUE(section.GetContents(&contents));
1222  ASSERT_BYTES(contents, I5(0x2a, 0x31, 0x2f, 0xb3, 0x40));
1223}
1224
1225TEST_F(Append, D64Big) {
1226  section.set_endianness(kBigEndian);
1227  section.Append(1, 0x2a);
1228  section.D64(0xb109843500dbcb16ULL);
1229  ASSERT_TRUE(section.GetContents(&contents));
1230  ASSERT_BYTES(contents,
1231               I9(0x2a, 0xb1, 0x09, 0x84, 0x35, 0x00, 0xdb, 0xcb, 0x16));
1232}
1233
1234TEST_F(Append, D64BigLabel) {
1235  Label l;
1236  section.set_endianness(kBigEndian);
1237  section.Append(1, 0x2a);
1238  section.D64(l);
1239  l = 0x9a0d61b70f671fd7ULL;
1240  ASSERT_TRUE(section.GetContents(&contents));
1241  ASSERT_BYTES(contents,
1242               I9(0x2a, 0x9a, 0x0d, 0x61, 0xb7, 0x0f, 0x67, 0x1f, 0xd7));
1243}
1244
1245TEST_F(Append, D8Little) {
1246  section.set_endianness(kLittleEndian);
1247  section.Append(1, 0x2a);
1248  section.D8(0x42U);
1249  ASSERT_TRUE(section.GetContents(&contents));
1250  ASSERT_BYTES(contents, I2(0x2a, 0x42));
1251}
1252
1253TEST_F(Append, D8LittleLabel) {
1254  Label l;
1255  section.set_endianness(kLittleEndian);
1256  section.Append(1, 0x2a);
1257  section.D8(l);
1258  l = 0x05U;
1259  ASSERT_TRUE(section.GetContents(&contents));
1260  ASSERT_BYTES(contents, I2(0x2a, 0x05));
1261}
1262
1263TEST_F(Append, D16Little) {
1264  section.set_endianness(kLittleEndian);
1265  section.Append(1, 0x2a);
1266  section.D16(0xc5c5U);
1267  ASSERT_TRUE(section.GetContents(&contents));
1268  ASSERT_BYTES(contents, I3(0x2a, 0xc5, 0xc5));
1269}
1270
1271TEST_F(Append, D16LittleLabel) {
1272  Label l;
1273  section.set_endianness(kLittleEndian);
1274  section.Append(1, 0x2a);
1275  section.D16(l);
1276  l = 0xb620U;
1277  ASSERT_TRUE(section.GetContents(&contents));
1278  ASSERT_BYTES(contents, I3(0x2a, 0x20, 0xb6));
1279}
1280
1281TEST_F(Append, D32Little) {
1282  section.set_endianness(kLittleEndian);
1283  section.Append(1, 0x2a);
1284  section.D32(0x1a87d0feU);
1285  ASSERT_TRUE(section.GetContents(&contents));
1286  ASSERT_BYTES(contents, I5(0x2a, 0xfe, 0xd0, 0x87, 0x1a));
1287}
1288
1289TEST_F(Append, D32LittleLabel) {
1290  Label l;
1291  section.set_endianness(kLittleEndian);
1292  section.Append(1, 0x2a);
1293  section.D32(l);
1294  l = 0xb8012d6bU;
1295  ASSERT_TRUE(section.GetContents(&contents));
1296  ASSERT_BYTES(contents, I5(0x2a, 0x6b, 0x2d, 0x01, 0xb8));
1297}
1298
1299TEST_F(Append, D64Little) {
1300  section.set_endianness(kLittleEndian);
1301  section.Append(1, 0x2a);
1302  section.D64(0x42de75c61375a1deULL);
1303  ASSERT_TRUE(section.GetContents(&contents));
1304  ASSERT_BYTES(contents,
1305               I9(0x2a, 0xde, 0xa1, 0x75, 0x13, 0xc6, 0x75, 0xde, 0x42));
1306}
1307
1308TEST_F(Append, D64LittleLabel) {
1309  Label l;
1310  section.set_endianness(kLittleEndian);
1311  section.Append(1, 0x2a);
1312  section.D64(l);
1313  l = 0x8b3bececf3fb5312ULL;
1314  ASSERT_TRUE(section.GetContents(&contents));
1315  ASSERT_BYTES(contents,
1316               I9(0x2a, 0x12, 0x53, 0xfb, 0xf3, 0xec, 0xec, 0x3b, 0x8b));
1317}
1318
1319TEST_F(Append, Variety) {
1320  Label a, b, c, d, e, f, g, h;
1321  section.Append(kBigEndian, 1, a)
1322      .Append(kLittleEndian, 8, h)
1323      .Append(kBigEndian, 1, 0x8bULL)
1324      .Append(kLittleEndian, 8, 0x0ea56540448f4439ULL)
1325      .Append(kBigEndian, 2, b)
1326      .Append(kLittleEndian, 7, g)
1327      .Append(kBigEndian, 2, 0xcf15ULL)
1328      .Append(kLittleEndian, 7, 0x29694f04c5724aULL)
1329      .Append(kBigEndian, 3, c)
1330      .Append(kLittleEndian, 6, f)
1331      .Append(kBigEndian, 3, 0x8c3ffdULL)
1332      .Append(kLittleEndian, 6, 0x6f11ba80187aULL)
1333      .Append(kBigEndian, 4, d)
1334      .Append(kLittleEndian, 5, e)
1335      .Append(kBigEndian, 4, 0x2fda2472ULL)
1336      .Append(kLittleEndian, 5, 0x0aa02d423fULL)
1337      .Append(kBigEndian, 5, e)
1338      .Append(kLittleEndian, 4, d)
1339      .Append(kBigEndian, 5, 0x53ba432138ULL)
1340      .Append(kLittleEndian, 4, 0xf139ae60ULL)
1341      .Append(kBigEndian, 6, f)
1342      .Append(kLittleEndian, 3, c)
1343      .Append(kBigEndian, 6, 0x168e436af716ULL)
1344      .Append(kLittleEndian, 3, 0x3ef189ULL)
1345      .Append(kBigEndian, 7, g)
1346      .Append(kLittleEndian, 2, b)
1347      .Append(kBigEndian, 7, 0xacd4ef233e47d9ULL)
1348      .Append(kLittleEndian, 2, 0x5311ULL)
1349      .Append(kBigEndian, 8, h)
1350      .Append(kLittleEndian, 1, a)
1351      .Append(kBigEndian, 8, 0x4668d5f1c93637a1ULL)
1352      .Append(kLittleEndian, 1, 0x65ULL);
1353  a = 0x79ac9bd8aa256b35ULL;
1354  b = 0x22d13097ef86c91cULL;
1355  c = 0xf204968b0a05862fULL;
1356  d = 0x163177f15a0eb4ecULL;
1357  e = 0xbd1b0f1d977f2246ULL;
1358  f = 0x2b0842eee83c6461ULL;
1359  g = 0x92f4b928a4bf875eULL;
1360  h = 0x61a199a8f7286ba6ULL;
1361  ASSERT_EQ(8 * 18U, section.Size());
1362  ASSERT_TRUE(section.GetContents(&contents));
1363
1364  static const u_int8_t expected[] = {
1365    0x35,    0xa6, 0x6b, 0x28, 0xf7, 0xa8, 0x99, 0xa1, 0x61,
1366    0x8b,    0x39, 0x44, 0x8f, 0x44, 0x40, 0x65, 0xa5, 0x0e,
1367    0xc9, 0x1c,    0x5e, 0x87, 0xbf, 0xa4, 0x28, 0xb9, 0xf4,
1368    0xcf, 0x15,    0x4a, 0x72, 0xc5, 0x04, 0x4f, 0x69, 0x29,
1369    0x05, 0x86, 0x2f,    0x61, 0x64, 0x3c, 0xe8, 0xee, 0x42,
1370    0x8c, 0x3f, 0xfd,    0x7a, 0x18, 0x80, 0xba, 0x11, 0x6f,
1371    0x5a, 0x0e, 0xb4, 0xec,    0x46, 0x22, 0x7f, 0x97, 0x1d,
1372    0x2f, 0xda, 0x24, 0x72,    0x3f, 0x42, 0x2d, 0xa0, 0x0a,
1373    0x1d, 0x97, 0x7f, 0x22, 0x46,    0xec, 0xb4, 0x0e, 0x5a,
1374    0x53, 0xba, 0x43, 0x21, 0x38,    0x60, 0xae, 0x39, 0xf1,
1375    0x42, 0xee, 0xe8, 0x3c, 0x64, 0x61,    0x2f, 0x86, 0x05,
1376    0x16, 0x8e, 0x43, 0x6a, 0xf7, 0x16,    0x89, 0xf1, 0x3e,
1377    0xf4, 0xb9, 0x28, 0xa4, 0xbf, 0x87, 0x5e,    0x1c, 0xc9,
1378    0xac, 0xd4, 0xef, 0x23, 0x3e, 0x47, 0xd9,    0x11, 0x53,
1379    0x61, 0xa1, 0x99, 0xa8, 0xf7, 0x28, 0x6b, 0xa6,    0x35,
1380    0x46, 0x68, 0xd5, 0xf1, 0xc9, 0x36, 0x37, 0xa1,    0x65,
1381  };
1382
1383  ASSERT_TRUE(0 == memcmp(contents.data(), expected, sizeof(expected)));
1384}
1385
1386TEST_F(Append, Section) {
1387  section.Append("murder");
1388  {
1389    Section middle;
1390    middle.Append(" she");
1391    section.Append(middle);
1392  }
1393  section.Append(" wrote");
1394  EXPECT_EQ(16U, section.Size());
1395  EXPECT_TRUE(section.GetContents(&contents));
1396  EXPECT_STREQ(contents.c_str(), "murder she wrote");
1397}
1398
1399TEST_F(Append, SectionRefs) {
1400  section.Append("sugar ");
1401  Label l;
1402  {
1403    Section middle;
1404    Label m;
1405    middle.B32(m);
1406    section.Append(middle);
1407    m = 0x66726565;
1408  }
1409  section.Append(" jazz");
1410  EXPECT_EQ(15U, section.Size());
1411  EXPECT_TRUE(section.GetContents(&contents));
1412  EXPECT_STREQ(contents.c_str(), "sugar free jazz");
1413}
1414
1415TEST_F(Append, LEB128_0) {
1416  section.LEB128(0);
1417  EXPECT_TRUE(section.GetContents(&contents));
1418  EXPECT_EQ(string("\0", 1), contents);
1419}
1420
1421TEST_F(Append, LEB128_0x3f) {
1422  section.LEB128(0x3f);
1423  EXPECT_TRUE(section.GetContents(&contents));
1424  EXPECT_EQ(string("\x3f", 1), contents);
1425}
1426
1427TEST_F(Append, LEB128_0x40) {
1428  section.LEB128(0x40);
1429  EXPECT_TRUE(section.GetContents(&contents));
1430  EXPECT_EQ(string("\xc0\x00", 2), contents);
1431}
1432
1433TEST_F(Append, LEB128_0x7f) {
1434  section.LEB128(0x7f);
1435  EXPECT_TRUE(section.GetContents(&contents));
1436  EXPECT_EQ(string("\xff\x00", 2), contents);
1437}
1438
1439TEST_F(Append, LEB128_0x80) {
1440  section.LEB128(0x80);
1441  EXPECT_TRUE(section.GetContents(&contents));
1442  EXPECT_EQ(string("\x80\x01", 2), contents);
1443}
1444
1445TEST_F(Append, LEB128_0xff) {
1446  section.LEB128(0xff);
1447  EXPECT_TRUE(section.GetContents(&contents));
1448  EXPECT_EQ(string("\xff\x01", 2), contents);
1449}
1450
1451TEST_F(Append, LEB128_0x1fff) {
1452  section.LEB128(0x1fff);
1453  EXPECT_TRUE(section.GetContents(&contents));
1454  EXPECT_EQ(string("\xff\x3f", 2), contents);
1455}
1456
1457TEST_F(Append, LEB128_0x2000) {
1458  section.LEB128(0x2000);
1459  EXPECT_TRUE(section.GetContents(&contents));
1460  EXPECT_EQ(string("\x80\xc0\x00", 3), contents);
1461}
1462
1463TEST_F(Append, LEB128_n1) {
1464  section.LEB128(-1);
1465  EXPECT_TRUE(section.GetContents(&contents));
1466  EXPECT_EQ(string("\x7f", 1), contents);
1467}
1468
1469TEST_F(Append, LEB128_n0x40) {
1470  section.LEB128(-0x40);
1471  EXPECT_TRUE(section.GetContents(&contents));
1472  EXPECT_EQ(string("\x40", 1), contents);
1473}
1474
1475TEST_F(Append, LEB128_n0x41) {
1476  section.LEB128(-0x41);
1477  EXPECT_TRUE(section.GetContents(&contents));
1478  EXPECT_EQ(string("\xbf\x7f", 2), contents);
1479}
1480
1481TEST_F(Append, LEB128_n0x7f) {
1482  section.LEB128(-0x7f);
1483  EXPECT_TRUE(section.GetContents(&contents));
1484  EXPECT_EQ(string("\x81\x7f", 2), contents);
1485}
1486
1487TEST_F(Append, LEB128_n0x80) {
1488  section.LEB128(-0x80);
1489  EXPECT_TRUE(section.GetContents(&contents));
1490  EXPECT_EQ(string("\x80\x7f", 2), contents);
1491}
1492
1493TEST_F(Append, LEB128_n0x2000) {
1494  section.LEB128(-0x2000);
1495  EXPECT_TRUE(section.GetContents(&contents));
1496  EXPECT_EQ(string("\x80\x40", 2), contents);
1497}
1498
1499TEST_F(Append, LEB128_n0x2001) {
1500  section.LEB128(-0x2001);
1501  EXPECT_TRUE(section.GetContents(&contents));
1502  EXPECT_EQ(string("\xff\xbf\x7f", 3), contents);
1503}
1504
1505TEST_F(Append,ULEB128_0) {
1506  section.ULEB128(0);
1507  EXPECT_TRUE(section.GetContents(&contents));
1508  EXPECT_EQ(string("\0", 1), contents);
1509}
1510
1511TEST_F(Append,ULEB128_1) {
1512  section.ULEB128(1);
1513  EXPECT_TRUE(section.GetContents(&contents));
1514  EXPECT_EQ(string("\x01", 1), contents);
1515}
1516
1517TEST_F(Append,ULEB128_0x3f) {
1518  section.ULEB128(0x3f);
1519  EXPECT_TRUE(section.GetContents(&contents));
1520  EXPECT_EQ(string("\x3f", 1), contents);
1521}
1522
1523TEST_F(Append,ULEB128_0x40) {
1524  section.ULEB128(0x40);
1525  EXPECT_TRUE(section.GetContents(&contents));
1526  EXPECT_EQ(string("\x40", 1), contents);
1527}
1528
1529TEST_F(Append,ULEB128_0x7f) {
1530  section.ULEB128(0x7f);
1531  EXPECT_TRUE(section.GetContents(&contents));
1532  EXPECT_EQ(string("\x7f", 1), contents);
1533}
1534
1535TEST_F(Append,ULEB128_0x80) {
1536  section.ULEB128(0x80);
1537  EXPECT_TRUE(section.GetContents(&contents));
1538  EXPECT_EQ(string("\x80\x01", 2), contents);
1539}
1540
1541TEST_F(Append,ULEB128_0xff) {
1542  section.ULEB128(0xff);
1543  EXPECT_TRUE(section.GetContents(&contents));
1544  EXPECT_EQ(string("\xff\x01", 2), contents);
1545}
1546
1547TEST_F(Append,ULEB128_0x100) {
1548  section.ULEB128(0x100);
1549  EXPECT_TRUE(section.GetContents(&contents));
1550  EXPECT_EQ(string("\x80\x02", 2), contents);
1551}
1552
1553TEST_F(Append,ULEB128_0x1fff) {
1554  section.ULEB128(0x1fff);
1555  EXPECT_TRUE(section.GetContents(&contents));
1556  EXPECT_EQ(string("\xff\x3f", 2), contents);
1557}
1558
1559TEST_F(Append,ULEB128_0x2000) {
1560  section.ULEB128(0x2000);
1561  EXPECT_TRUE(section.GetContents(&contents));
1562  EXPECT_EQ(string("\x80\x40", 2), contents);
1563}
1564
1565TEST_F(Append,ULEB128_0x3fff) {
1566  section.ULEB128(0x3fff);
1567  EXPECT_TRUE(section.GetContents(&contents));
1568  EXPECT_EQ(string("\xff\x7f", 2), contents);
1569}
1570
1571TEST_F(Append,ULEB128_0x4000) {
1572  section.ULEB128(0x4000);
1573  EXPECT_TRUE(section.GetContents(&contents));
1574  EXPECT_EQ(string("\x80\x80\x01", 3), contents);
1575}
1576
1577TEST_F(Append,ULEB128_12857) {
1578  section.ULEB128(12857);
1579  EXPECT_TRUE(section.GetContents(&contents));
1580  EXPECT_EQ(string("\xb9\x64", 2), contents);
1581}
1582
1583TEST_F(Append, LEBChain) {
1584  section.LEB128(-0x80).ULEB128(12857).Append("*");
1585  EXPECT_TRUE(section.GetContents(&contents));
1586  EXPECT_EQ(string("\x80\x7f\xb9\x64*", 5), contents);
1587}
1588
1589
1590class GetContents: public SectionFixture, public Test { };
1591
1592TEST_F(GetContents, Undefined) {
1593  Label l;
1594  section.Append(kLittleEndian, 8, l);
1595  ASSERT_FALSE(section.GetContents(&contents));
1596}
1597
1598TEST_F(GetContents, ClearsContents) {
1599  section.Append((size_t) 10, '*');
1600  EXPECT_EQ(10U, section.Size());
1601  EXPECT_TRUE(section.GetContents(&contents));
1602  EXPECT_EQ(0U, section.Size());
1603}
1604
1605TEST_F(GetContents, ClearsReferences) {
1606  Label l;
1607  section.Append(kBigEndian, 1, l);
1608  l = 42;
1609  ASSERT_TRUE(section.GetContents(&contents));
1610  ASSERT_BYTES(contents, I1(42));
1611  ASSERT_TRUE(section.GetContents(&contents)); // should not die
1612}
1613
1614class Miscellanea: public SectionFixture, public Test { };
1615
1616TEST_F(Miscellanea, Clear) {
1617  section.Append("howdy");
1618  Label l;
1619  section.L32(l);
1620  EXPECT_EQ(9U, section.Size());
1621  section.Clear();
1622  EXPECT_EQ(0U, section.Size());
1623  l = 0x8d231bf0U;
1624  ASSERT_TRUE(section.GetContents(&contents)); // should not die
1625}
1626
1627TEST_F(Miscellanea, Align) {
1628  section.Append("*");
1629  EXPECT_EQ(1U, section.Size());
1630  section.Align(4).Append("*");
1631  EXPECT_EQ(5U, section.Size());
1632  section.Append("*").Align(2);
1633  EXPECT_EQ(6U, section.Size());
1634}
1635
1636TEST_F(Miscellanea, AlignPad) {
1637  section.Append("*");
1638  EXPECT_EQ(1U, section.Size());
1639  section.Align(4, ' ').Append("*");
1640  EXPECT_EQ(5U, section.Size());
1641  section.Append("*").Align(2, ' ');
1642  EXPECT_EQ(6U, section.Size());
1643  ASSERT_TRUE(section.GetContents(&contents));
1644  ASSERT_EQ(string("*   **"), contents);
1645}
1646
1647TEST_F(Miscellanea, StartHereMark) {
1648  Label m;
1649  section.Append(42, ' ').Mark(&m).Append(13, '+');
1650  EXPECT_EQ(42U, m - section.start());
1651  EXPECT_EQ(42U + 13U, section.Here() - section.start());
1652  EXPECT_FALSE(section.start().IsKnownConstant());
1653  EXPECT_FALSE(m.IsKnownConstant());
1654  EXPECT_FALSE(section.Here().IsKnownConstant());
1655}
1656
1657TEST_F(Miscellanea, Endianness) {
1658  section.set_endianness(kBigEndian);
1659  EXPECT_EQ(kBigEndian, section.endianness());
1660  section.set_endianness(kLittleEndian);
1661  EXPECT_EQ(kLittleEndian, section.endianness());
1662}
1663