[dev.boringcrypto] all: merge master into dev.boringcrypto

Conflicts due to simple variable renames (d <-> d0):
    src/crypto/sha1/sha1.go
    src/crypto/sha256/sha256.go
    src/crypto/sha512/sha512.go

Change-Id: I437df180a527fb3ec8b47927ee71960d5d200b76
This commit is contained in:
Filippo Valsorda 2018-05-17 21:04:07 -04:00
commit a3f9ce3313
1997 changed files with 211360 additions and 117222 deletions

View file

@ -1,7 +1,25 @@
Please do not send pull requests to the golang/* repositories. This PR will be imported into Gerrit with the title and first
comment (this text) used to generate the subject and body of
the Gerrit change.
We do, however, take contributions gladly. **Please ensure you adhere to every item in this list.**
See https://golang.org/doc/contribute.html More info can be found at https://github.com/golang/go/wiki/CommitMessage
Thanks! + The PR title is formatted as follows: `net/http: frob the quux before blarfing`
+ The package name goes before the colon
+ The part after the colon uses the verb tense + phrase that completes the blank in,
"This change modifies Go to ___________"
+ Lowercase verb after the colon
+ No trailing period
+ Keep the title as short as possible. ideally under 76 characters or shorter
+ No Markdown
+ The first PR comment (this one) is wrapped at 76 characters, unless it's
really needed (ASCII art, table, or long link)
+ If there is a corresponding issue, add either `Fixes #1234` or `Updates #1234`
(the latter if this is not a complete fix) to this comment
+ If referring to a repo other than `golang/go` you can use the
`owner/repo#issue_number` syntax: `Fixes golang/tools#1234`
+ We do not use Signed-off-by lines in Go. Please don't add them.
Our Gerrit server & GitHub bots enforce CLA compliance instead.
+ Delete these instructions once you have read and applied them

159
AUTHORS
View file

@ -18,13 +18,18 @@ Abe Haskins <abeisgreat@abeisgreat.com>
Abhinav Gupta <abhinav.g90@gmail.com> Abhinav Gupta <abhinav.g90@gmail.com>
Adam Eijdenberg <adam@continusec.com> Adam Eijdenberg <adam@continusec.com>
Adam Kisala <adam.kisala@gmail.com> Adam Kisala <adam.kisala@gmail.com>
Adam Thomason <athomason@gmail.com>
Aditya Mukerjee <dev@chimeracoder.net> Aditya Mukerjee <dev@chimeracoder.net>
Adrian Hesketh <adrianhesketh@hushmail.com>
Adrian Nos <nos.adrian@gmail.com> Adrian Nos <nos.adrian@gmail.com>
Adrian O'Grady <elpollouk@gmail.com> Adrian O'Grady <elpollouk@gmail.com>
Adrien Bustany <adrien-xx-google@bustany.org> Adrien Bustany <adrien-xx-google@bustany.org>
Aécio Júnior <aeciodantasjunior@gmail.com> Aécio Júnior <aeciodantasjunior@gmail.com>
Aeneas Rekkas (arekkas) <aeneas@ory.am>
Afanasev Stanislav <phpprogger@gmail.com>
Agis Anastasopoulos <agis.anast@gmail.com> Agis Anastasopoulos <agis.anast@gmail.com>
Ahmed Waheed Moanes <oneofone@gmail.com> Agniva De Sarker <agnivade@yahoo.co.in>
Ahmed Wahed <oneofone@gmail.com>
Ahmy Yulrizka <yulrizka@gmail.com> Ahmy Yulrizka <yulrizka@gmail.com>
Aiden Scandella <ai@uber.com> Aiden Scandella <ai@uber.com>
Ainar Garipov <gugl.zadolbal@gmail.com> Ainar Garipov <gugl.zadolbal@gmail.com>
@ -60,6 +65,7 @@ Alexander Menzhinsky <amenzhinsky@gmail.com>
Alexander Morozov <lk4d4math@gmail.com> Alexander Morozov <lk4d4math@gmail.com>
Alexander Neumann <alexander@bumpern.de> Alexander Neumann <alexander@bumpern.de>
Alexander Orlov <alexander.orlov@loxal.net> Alexander Orlov <alexander.orlov@loxal.net>
Alexander Pantyukhin <apantykhin@gmail.com>
Alexander Reece <awreece@gmail.com> Alexander Reece <awreece@gmail.com>
Alexander Surma <surma@surmair.de> Alexander Surma <surma@surmair.de>
Alexander Zhavnerchik <alex.vizor@gmail.com> Alexander Zhavnerchik <alex.vizor@gmail.com>
@ -67,6 +73,7 @@ Alexander Zolotov <goldifit@gmail.com>
Alexandre Cesaro <alexandre.cesaro@gmail.com> Alexandre Cesaro <alexandre.cesaro@gmail.com>
Alexandre Fiori <fiorix@gmail.com> Alexandre Fiori <fiorix@gmail.com>
Alexandre Normand <alexandre.normand@gmail.com> Alexandre Normand <alexandre.normand@gmail.com>
Alexandre Parentea <aubonbeurre@gmail.com>
Alexei Sholik <alcosholik@gmail.com> Alexei Sholik <alcosholik@gmail.com>
Alexey Borzenkov <snaury@gmail.com> Alexey Borzenkov <snaury@gmail.com>
Alexey Neganov <neganovalexey@gmail.com> Alexey Neganov <neganovalexey@gmail.com>
@ -76,9 +83,11 @@ Aliaksandr Valialkin <valyala@gmail.com>
Alif Rachmawadi <subosito@gmail.com> Alif Rachmawadi <subosito@gmail.com>
Allan Simon <allan.simon@supinfo.com> Allan Simon <allan.simon@supinfo.com>
Alok Menghrajani <alok.menghrajani@gmail.com> Alok Menghrajani <alok.menghrajani@gmail.com>
Aman Gupta <aman@tmm1.net>
Amazon.com, Inc Amazon.com, Inc
Amir Mohammad Saied <amir@gluegadget.com> Amir Mohammad Saied <amir@gluegadget.com>
Amrut Joshi <amrut.joshi@gmail.com> Amrut Joshi <amrut.joshi@gmail.com>
Anand K. Mistry <anand@mistry.ninja>
Anders Pearson <anders@columbia.edu> Anders Pearson <anders@columbia.edu>
André Carvalho <asantostc@gmail.com> André Carvalho <asantostc@gmail.com>
Andre Nathan <andrenth@gmail.com> Andre Nathan <andrenth@gmail.com>
@ -104,7 +113,10 @@ Andrew Wilkins <axwalk@gmail.com>
Andrew Williams <williams.andrew@gmail.com> Andrew Williams <williams.andrew@gmail.com>
Andrey Mirtchovski <mirtchovski@gmail.com> Andrey Mirtchovski <mirtchovski@gmail.com>
Andrey Petrov <andrey.petrov@shazow.net> Andrey Petrov <andrey.petrov@shazow.net>
Andrii Soldatenko <andrii.soldatenko@gmail.com>
Andrii Soluk <isoluchok@gmail.com>
Andriy Lytvynov <lytvynov.a.v@gmail.com> Andriy Lytvynov <lytvynov.a.v@gmail.com>
Andrzej Żeżel <andrii.zhezhel@gmail.com>
Andy Balholm <andy@balholm.com> Andy Balholm <andy@balholm.com>
Andy Davis <andy@bigandian.com> Andy Davis <andy@bigandian.com>
Andy Finkenstadt <afinkenstadt@zynga.com> Andy Finkenstadt <afinkenstadt@zynga.com>
@ -115,9 +127,11 @@ Angelo Bulfone <mbulfone@gmail.com>
Anh Hai Trinh <anh.hai.trinh@gmail.com> Anh Hai Trinh <anh.hai.trinh@gmail.com>
Anmol Sethi <anmol@aubble.com> Anmol Sethi <anmol@aubble.com>
Anschel Schaffer-Cohen <anschelsc@gmail.com> Anschel Schaffer-Cohen <anschelsc@gmail.com>
Anthony Alves <cvballa3g0@gmail.com>
Anthony Canino <anthony.canino1@gmail.com> Anthony Canino <anthony.canino1@gmail.com>
Anthony Eufemio <anthony.eufemio@gmail.com> Anthony Eufemio <anthony.eufemio@gmail.com>
Anthony Martin <ality@pbrane.org> Anthony Martin <ality@pbrane.org>
Anthony Sottile <asottile@umich.edu>
Anthony Starks <ajstarks@gmail.com> Anthony Starks <ajstarks@gmail.com>
Anthony Voutas <voutasaurus@gmail.com> Anthony Voutas <voutasaurus@gmail.com>
Anthony Woods <awoods@raintank.io> Anthony Woods <awoods@raintank.io>
@ -128,6 +142,7 @@ Apisak Darakananda <pongad@gmail.com>
Apsalar Apsalar
Aram Hăvărneanu <aram@mgk.ro> Aram Hăvărneanu <aram@mgk.ro>
Areski Belaid <areski@gmail.com> Areski Belaid <areski@gmail.com>
Ariel Mashraki <ariel@mashraki.co.il>
Arlo Breault <arlolra@gmail.com> Arlo Breault <arlolra@gmail.com>
ARM Ltd. ARM Ltd.
Arnaud Ysmal <arnaud.ysmal@gmail.com> Arnaud Ysmal <arnaud.ysmal@gmail.com>
@ -143,12 +158,14 @@ Augusto Roman <aroman@gmail.com>
Aulus Egnatius Varialus <varialus@gmail.com> Aulus Egnatius Varialus <varialus@gmail.com>
awaw fumin <awawfumin@gmail.com> awaw fumin <awawfumin@gmail.com>
Awn Umar <awn@cryptolosophy.io> Awn Umar <awn@cryptolosophy.io>
Axel Wagner <axel.wagner.hh@googlemail.com>
Ayanamist Yang <ayanamist@gmail.com> Ayanamist Yang <ayanamist@gmail.com>
Aymerick Jéhanne <aymerick@jehanne.org> Aymerick Jéhanne <aymerick@jehanne.org>
Baiju Muthukadan <baiju.m.mail@gmail.com> Baiju Muthukadan <baiju.m.mail@gmail.com>
Bartosz Grzybowski <melkorm@gmail.com> Bartosz Grzybowski <melkorm@gmail.com>
Bastian Ike <bastian.ike@gmail.com> Bastian Ike <bastian.ike@gmail.com>
Ben Burkert <ben@benburkert.com> Ben Burkert <ben@benburkert.com>
Ben Haines <bhainesva@gmail.com>
Ben Lubar <ben.lubar@gmail.com> Ben Lubar <ben.lubar@gmail.com>
Ben Olive <sionide21@gmail.com> Ben Olive <sionide21@gmail.com>
Ben Shi <powerman1st@163.com> Ben Shi <powerman1st@163.com>
@ -159,26 +176,33 @@ Berengar Lehr <berengar.lehr@gmx.de>
Billie Harold Cleek <bhcleek@gmail.com> Billie Harold Cleek <bhcleek@gmail.com>
Bjorn Tillenius <bjorn@tillenius.me> Bjorn Tillenius <bjorn@tillenius.me>
Bjorn Tipling <bjorn.tipling@gmail.com> Bjorn Tipling <bjorn.tipling@gmail.com>
Blain Smith <rebelgeek@blainsmith.com>
Blake Gentry <blakesgentry@gmail.com> Blake Gentry <blakesgentry@gmail.com>
Blake Mesdag <blakemesdag@gmail.com>
Blake Mizerany <blake.mizerany@gmail.com> Blake Mizerany <blake.mizerany@gmail.com>
Blixt <me@blixt.nyc> Blixt <me@blixt.nyc>
Bobby Powers <bobbypowers@gmail.com> Bobby Powers <bobbypowers@gmail.com>
Bolt Bolt
Borja Clemente <borja.clemente@gmail.com>
Brad Burch <brad.burch@gmail.com>
Brady Catherman <brady@gmail.com> Brady Catherman <brady@gmail.com>
Brady Sullivan <brady@bsull.com> Brady Sullivan <brady@bsull.com>
Brendan Daniel Tracey <tracey.brendan@gmail.com> Brendan Daniel Tracey <tracey.brendan@gmail.com>
Brett Cannon <bcannon@gmail.com> Brett Cannon <bcannon@gmail.com>
Brett Merrill <brett.j.merrill94@gmail.com>
Brian Dellisanti <briandellisanti@gmail.com> Brian Dellisanti <briandellisanti@gmail.com>
Brian Downs <brian.downs@gmail.com> Brian Downs <brian.downs@gmail.com>
Brian G. Merrell <bgmerrell@gmail.com> Brian G. Merrell <bgmerrell@gmail.com>
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com>
Brian Kennedy <btkennedy@gmail.com> Brian Kennedy <btkennedy@gmail.com>
Brian Kessler <brian.m.kessler@gmail.com>
Brian Ketelsen <bketelsen@gmail.com> Brian Ketelsen <bketelsen@gmail.com>
Brian Smith <ohohvi@gmail.com> Brian Smith <ohohvi@gmail.com>
Brian Starke <brian.starke@gmail.com> Brian Starke <brian.starke@gmail.com>
Bryan Alexander <Kozical@msn.com> Bryan Alexander <Kozical@msn.com>
Bryan Ford <brynosaurus@gmail.com> Bryan Ford <brynosaurus@gmail.com>
Bulat Gaifullin <gaifullinbf@gmail.com> Bulat Gaifullin <gaifullinbf@gmail.com>
Burak Guven <bguven@gmail.com>
Caine Tighe <arctanofyourface@gmail.com> Caine Tighe <arctanofyourface@gmail.com>
Caleb Spare <cespare@gmail.com> Caleb Spare <cespare@gmail.com>
Carl Chatfield <carlchatfield@gmail.com> Carl Chatfield <carlchatfield@gmail.com>
@ -193,9 +217,12 @@ Case Nelson <case.nelson@gmail.com>
Casey Marshall <casey.marshall@gmail.com> Casey Marshall <casey.marshall@gmail.com>
Cezar Sá Espinola <cezarsa@gmail.com> Cezar Sá Espinola <cezarsa@gmail.com>
ChaiShushan <chaishushan@gmail.com> ChaiShushan <chaishushan@gmail.com>
Charles Fenwick Elliott <Charles@FenwickElliott.io>
Charles L. Dorian <cldorian@gmail.com> Charles L. Dorian <cldorian@gmail.com>
Charles Lee <zombie.fml@gmail.com> Charles Lee <zombie.fml@gmail.com>
Chew Choon Keat <choonkeat@gmail.com> Chew Choon Keat <choonkeat@gmail.com>
Cholerae Hu <choleraehyq@gmail.com>
Chris Ball <chris@printf.net>
Chris Biscardi <chris@christopherbiscardi.com> Chris Biscardi <chris@christopherbiscardi.com>
Chris Dollin <ehog.hedge@gmail.com> Chris Dollin <ehog.hedge@gmail.com>
Chris Farmiloe <chrisfarms@gmail.com> Chris Farmiloe <chrisfarms@gmail.com>
@ -207,6 +234,7 @@ Chris Lennert <calennert@gmail.com>
Chris McGee <sirnewton_01@yahoo.ca> <newton688@gmail.com> Chris McGee <sirnewton_01@yahoo.ca> <newton688@gmail.com>
Chris Roche <rodaine@gmail.com> Chris Roche <rodaine@gmail.com>
Chris Stockton <chrisstocktonaz@gmail.com> Chris Stockton <chrisstocktonaz@gmail.com>
Christian Alexander <christian@linux.com>
Christian Couder <chriscool@tuxfamily.org> Christian Couder <chriscool@tuxfamily.org>
Christian Himpel <chressie@googlemail.com> Christian Himpel <chressie@googlemail.com>
Christine Hansmann <chhansmann@gmail.com> Christine Hansmann <chhansmann@gmail.com>
@ -214,10 +242,12 @@ Christoffer Buchholz <christoffer.buchholz@gmail.com>
Christoph Hack <christoph@tux21b.org> Christoph Hack <christoph@tux21b.org>
Christopher Cahoon <chris.cahoon@gmail.com> Christopher Cahoon <chris.cahoon@gmail.com>
Christopher Guiney <chris@guiney.net> Christopher Guiney <chris@guiney.net>
Christopher Henderson <chris@chenderson.org>
Christopher Nelson <nadiasvertex@gmail.com> Christopher Nelson <nadiasvertex@gmail.com>
Christopher Nielsen <m4dh4tt3r@gmail.com> Christopher Nielsen <m4dh4tt3r@gmail.com>
Christopher Redden <christopher.redden@gmail.com> Christopher Redden <christopher.redden@gmail.com>
Christopher Wedgwood <cw@f00f.org> Christopher Wedgwood <cw@f00f.org>
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
CL Sung <clsung@gmail.com> <cl_sung@htc.com> CL Sung <clsung@gmail.com> <cl_sung@htc.com>
Clement Skau <clementskau@gmail.com> Clement Skau <clementskau@gmail.com>
CloudFlare Inc. CloudFlare Inc.
@ -251,6 +281,8 @@ Daniel Skinner <daniel@dasa.cc>
Daniel Speichert <daniel@speichert.pl> Daniel Speichert <daniel@speichert.pl>
Daniel Theophanes <kardianos@gmail.com> Daniel Theophanes <kardianos@gmail.com>
Daniel Upton <daniel@floppy.co> Daniel Upton <daniel@floppy.co>
Daniela Petruzalek <daniela.petruzalek@gmail.com>
Danny Rosseau <daniel.rosseau@gmail.com>
Darren Elwood <darren@textnode.com> Darren Elwood <darren@textnode.com>
Datong Sun <dndx@idndx.com> Datong Sun <dndx@idndx.com>
Dave Cheney <dave@cheney.net> Dave Cheney <dave@cheney.net>
@ -272,6 +304,7 @@ David Thomas <davidthomas426@gmail.com>
David Titarenco <david.titarenco@gmail.com> David Titarenco <david.titarenco@gmail.com>
David Volquartz Lebech <david@lebech.info> David Volquartz Lebech <david@lebech.info>
Davies Liu <davies.liu@gmail.com> Davies Liu <davies.liu@gmail.com>
Davor Kapsa <davor.kapsa@gmail.com>
Dean Prichard <dean.prichard@gmail.com> Dean Prichard <dean.prichard@gmail.com>
Deepak Jois <deepak.jois@gmail.com> Deepak Jois <deepak.jois@gmail.com>
Denis Bernard <db047h@gmail.com> Denis Bernard <db047h@gmail.com>
@ -308,15 +341,19 @@ Dustin Sallings <dsallings@gmail.com>
Dustin Shields-Cloues <dcloues@gmail.com> Dustin Shields-Cloues <dcloues@gmail.com>
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com> Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
Dylan Waits <dylan@waits.io> Dylan Waits <dylan@waits.io>
Edan Bedrik <3d4nb3@gmail.com>
Eden Li <eden.li@gmail.com> Eden Li <eden.li@gmail.com>
Edward Muller <edwardam@interlix.com> Edward Muller <edwardam@interlix.com>
Egon Elbre <egonelbre@gmail.com> Egon Elbre <egonelbre@gmail.com>
Ehren Kret <ehren.kret@gmail.com> Ehren Kret <ehren.kret@gmail.com>
Eitan Adler <lists@eitanadler.com> Eitan Adler <lists@eitanadler.com>
Eivind Uggedal <eivind@uggedal.com> Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com>
Elena Grahovac <elena@grahovac.me>
Elias Naur <elias.naur@gmail.com> Elias Naur <elias.naur@gmail.com>
Elliot Morrison-Reed <elliotmr@gmail.com> Elliot Morrison-Reed <elliotmr@gmail.com>
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se> Emerson Lin <linyintor@gmail.com>
Emil Hessman <emil@hessman.se>
Emilien Kenler <hello@emilienkenler.com> Emilien Kenler <hello@emilienkenler.com>
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca> Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
Empirical Interfaces Inc. Empirical Interfaces Inc.
@ -326,6 +363,7 @@ Eric Clark <zerohp@gmail.com>
Eric Engestrom <eric@engestrom.ch> Eric Engestrom <eric@engestrom.ch>
Eric Lagergren <ericscottlagergren@gmail.com> Eric Lagergren <ericscottlagergren@gmail.com>
Eric Milliken <emilliken@gmail.com> Eric Milliken <emilliken@gmail.com>
Eric Rescorla <ekr@rtfm.com>
Eric Roshan-Eisner <eric.d.eisner@gmail.com> Eric Roshan-Eisner <eric.d.eisner@gmail.com>
Erik Aigner <aigner.erik@gmail.com> Erik Aigner <aigner.erik@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com> Erik Dubbelboer <erik@dubbelboer.com>
@ -335,6 +373,7 @@ Ernest Chiang <ernest_chiang@htc.com>
Esko Luontola <esko.luontola@gmail.com> Esko Luontola <esko.luontola@gmail.com>
Euan Kemp <euank@euank.com> Euan Kemp <euank@euank.com>
Evan Hicks <evan.hicks2@gmail.com> Evan Hicks <evan.hicks2@gmail.com>
Evan Jones <ej@evanjones.ca>
Evan Phoenix <evan@phx.io> Evan Phoenix <evan@phx.io>
Evan Shaw <chickencha@gmail.com> Evan Shaw <chickencha@gmail.com>
Evgeniy Polyakov <zbr@ioremap.net> Evgeniy Polyakov <zbr@ioremap.net>
@ -363,6 +402,8 @@ Ford Hurley <ford.hurley@gmail.com>
Francisco Claude <fclaude@recoded.cl> Francisco Claude <fclaude@recoded.cl>
Francisco Rojas <francisco.rojas.gallegos@gmail.com> Francisco Rojas <francisco.rojas.gallegos@gmail.com>
Francisco Souza <franciscossouza@gmail.com> Francisco Souza <franciscossouza@gmail.com>
Frank Somers <fsomers@arista.com>
Frederic Guillot <frederic.guillot@gmail.com>
Frederick Kelly Mayle III <frederickmayle@gmail.com> Frederick Kelly Mayle III <frederickmayle@gmail.com>
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com> Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
Fredrik Forsmo <fredrik.forsmo@gmail.com> Fredrik Forsmo <fredrik.forsmo@gmail.com>
@ -391,9 +432,12 @@ Google Inc.
Gordon Klaus <gordon.klaus@gmail.com> Gordon Klaus <gordon.klaus@gmail.com>
Graham King <graham4king@gmail.com> Graham King <graham4king@gmail.com>
Graham Miller <graham.miller@gmail.com> Graham Miller <graham.miller@gmail.com>
Grant Griffiths <ggp493@gmail.com>
Greg Poirier <greg.istehbest@gmail.com> Greg Poirier <greg.istehbest@gmail.com>
Greg Ward <greg@gerg.ca> Greg Ward <greg@gerg.ca>
Gregory Man <man.gregory@gmail.com> Gregory Man <man.gregory@gmail.com>
Guilherme Garnier <guilherme.garnier@gmail.com>
Guilherme Rezende <guilhermebr@gmail.com>
Guillaume J. Charmes <guillaume@charmes.net> Guillaume J. Charmes <guillaume@charmes.net>
Guobiao Mei <meiguobiao@gmail.com> Guobiao Mei <meiguobiao@gmail.com>
Gustav Paul <gustav.paul@gmail.com> Gustav Paul <gustav.paul@gmail.com>
@ -404,6 +448,7 @@ Gyu-Ho Lee <gyuhox@gmail.com>
H. İbrahim Güngör <igungor@gmail.com> H. İbrahim Güngör <igungor@gmail.com>
Hajime Hoshi <hajimehoshi@gmail.com> Hajime Hoshi <hajimehoshi@gmail.com>
Hang Qian <hangqian90@gmail.com> Hang Qian <hangqian90@gmail.com>
Hanjun Kim <hallazzang@gmail.com>
Hari haran <hariharan.uno@gmail.com> Hari haran <hariharan.uno@gmail.com>
Hariharan Srinath <srinathh@gmail.com> Hariharan Srinath <srinathh@gmail.com>
Harley Laue <losinggeneration@gmail.com> Harley Laue <losinggeneration@gmail.com>
@ -416,8 +461,12 @@ Hector Martin Cantero <hector@marcansoft.com>
Henning Schmiedehausen <henning@schmiedehausen.org> Henning Schmiedehausen <henning@schmiedehausen.org>
Henrik Edwards <henrik.edwards@gmail.com> Henrik Edwards <henrik.edwards@gmail.com>
Henrik Hodne <henrik@hodne.io> Henrik Hodne <henrik@hodne.io>
Henry Adi Sumarto <henry.adisumarto@gmail.com>
Henry Bubert <google@mindeco.de>
Henry Chang <mr.changyuheng@gmail.com> Henry Chang <mr.changyuheng@gmail.com>
Herbert Georg Fischer <herbert.fischer@gmail.com> Herbert Georg Fischer <herbert.fischer@gmail.com>
Hilko Bengen <bengen@hilluzination.de>
Hiroaki Nakamura <hnakamur@gmail.com>
Hironao OTSUBO <motemen@gmail.com> Hironao OTSUBO <motemen@gmail.com>
Hiroshi Ioka <hirochachacha@gmail.com> Hiroshi Ioka <hirochachacha@gmail.com>
Hitoshi Mitake <mitake.hitoshi@gmail.com> Hitoshi Mitake <mitake.hitoshi@gmail.com>
@ -428,6 +477,7 @@ Hsin-Ho Yeh <yhh92u@gmail.com>
Hu Keping <hukeping@huawei.com> Hu Keping <hukeping@huawei.com>
Hugues Bruant <hugues.bruant@gmail.com> Hugues Bruant <hugues.bruant@gmail.com>
Ian Gudger <ian@loosescre.ws> Ian Gudger <ian@loosescre.ws>
Ian Kent <iankent85@gmail.com>
IBM IBM
Ibrahim AshShohail <ibra.sho@gmail.com> Ibrahim AshShohail <ibra.sho@gmail.com>
Icarus Sparry <golang@icarus.freeuk.com> Icarus Sparry <golang@icarus.freeuk.com>
@ -435,13 +485,16 @@ Iccha Sethi <icchasethi@gmail.com>
Idora Shinatose <idora.shinatose@gmail.com> Idora Shinatose <idora.shinatose@gmail.com>
Igneous Systems, Inc. Igneous Systems, Inc.
Igor Dolzhikov <bluesriverz@gmail.com> Igor Dolzhikov <bluesriverz@gmail.com>
Igor Vashyst <ivashyst@gmail.com>
INADA Naoki <songofacandy@gmail.com> INADA Naoki <songofacandy@gmail.com>
Inanc Gumus <m@inanc.io>
Ingo Krabbe <ikrabbe.ask@gmail.com> Ingo Krabbe <ikrabbe.ask@gmail.com>
Ingo Oeser <nightlyone@googlemail.com> Ingo Oeser <nightlyone@googlemail.com>
Intel Corporation Intel Corporation
Irieda Noboru <irieda@gmail.com> Irieda Noboru <irieda@gmail.com>
Isaac Wagner <ibw@isaacwagner.me> Isaac Wagner <ibw@isaacwagner.me>
Ivan Babrou <ivan@cloudflare.com> Ivan Babrou <ivan@cloudflare.com>
Ivan Bertona <ivan.bertona@gmail.com>
Ivan Moscoso <moscoso@gmail.com> Ivan Moscoso <moscoso@gmail.com>
Ivan Ukhov <ivan.ukhov@gmail.com> Ivan Ukhov <ivan.ukhov@gmail.com>
Jacob Hoffman-Andrews <github@hoffman-andrews.com> Jacob Hoffman-Andrews <github@hoffman-andrews.com>
@ -455,6 +508,7 @@ James David Chalfant <james.chalfant@gmail.com>
James Fysh <james.fysh@gmail.com> James Fysh <james.fysh@gmail.com>
James Gray <james@james4k.com> James Gray <james@james4k.com>
James Hartig <fastest963@gmail.com> James Hartig <fastest963@gmail.com>
James Lawrence <jljatone@gmail.com>
James Meneghello <rawrz0r@gmail.com> James Meneghello <rawrz0r@gmail.com>
James Myers <jfmyers9@gmail.com> James Myers <jfmyers9@gmail.com>
James Neve <jamesoneve@gmail.com> James Neve <jamesoneve@gmail.com>
@ -463,6 +517,7 @@ James Schofield <james@shoeboxapp.com>
James Smith <jrs1995@icloud.com> James Smith <jrs1995@icloud.com>
James Sweet <james.sweet88@googlemail.com> James Sweet <james.sweet88@googlemail.com>
James Toy <nil@opensesame.st> James Toy <nil@opensesame.st>
James Treanor <jtreanor3@gmail.com>
James Whitehead <jnwhiteh@gmail.com> James Whitehead <jnwhiteh@gmail.com>
Jamie Beverly <jamie.r.beverly@gmail.com> Jamie Beverly <jamie.r.beverly@gmail.com>
Jamie Kerr <jkerr113@googlemail.com> Jamie Kerr <jkerr113@googlemail.com>
@ -474,19 +529,25 @@ Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
Jan Newmarch <jan.newmarch@gmail.com> Jan Newmarch <jan.newmarch@gmail.com>
Jan Ziak <0xe2.0x9a.0x9b@gmail.com> Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
Jani Monoses <jani.monoses@ubuntu.com> Jani Monoses <jani.monoses@ubuntu.com>
Jared Culp <jculp14@gmail.com>
Jaroslavas Počepko <jp@webmaster.ms> Jaroslavas Počepko <jp@webmaster.ms>
Jason Barnett <jason.w.barnett@gmail.com> Jason Barnett <jason.w.barnett@gmail.com>
Jason Chu <jasonchujc@gmail.com> Jason Chu <jasonchujc@gmail.com>
Jason Del Ponte <delpontej@gmail.com> Jason Del Ponte <delpontej@gmail.com>
Jason Smale <jsmale@zendesk.com> Jason Smale <jsmale@zendesk.com>
Jason Travis <infomaniac7@gmail.com> Jason Travis <infomaniac7@gmail.com>
Jason Wangsadinata <jwangsadinata@gmail.com>
Javier Segura <javism@gmail.com>
Jay Weisskopf <jay@jayschwa.net> Jay Weisskopf <jay@jayschwa.net>
Jean-Francois Cantin <jfcantin@gmail.com>
Jean-Nicolas Moal <jn.moal@gmail.com> Jean-Nicolas Moal <jn.moal@gmail.com>
Jeet Parekh <jeetparekh96@gmail.com>
Jeff Hodges <jeff@somethingsimilar.com> Jeff Hodges <jeff@somethingsimilar.com>
Jeff R. Allen <jra@nella.org> Jeff R. Allen <jra@nella.org>
Jeff Sickel <jas@corpus-callosum.com> Jeff Sickel <jas@corpus-callosum.com>
Jeff Wendling <jeff@spacemonkey.com> Jeff Wendling <jeff@spacemonkey.com>
Jeffrey H <jeffreyh192@gmail.com> Jeffrey H <jeffreyh192@gmail.com>
Jelte Fennema <github-tech@jeltef.nl>
Jens Frederich <jfrederich@gmail.com> Jens Frederich <jfrederich@gmail.com>
Jeremy Jackins <jeremyjackins@gmail.com> Jeremy Jackins <jeremyjackins@gmail.com>
Jeroen Bobbeldijk <jerbob92@gmail.com> Jeroen Bobbeldijk <jerbob92@gmail.com>
@ -494,12 +555,14 @@ Jess Frazelle <me@jessfraz.com>
Jesse Szwedko <jesse.szwedko@gmail.com> Jesse Szwedko <jesse.szwedko@gmail.com>
Jihyun Yu <yjh0502@gmail.com> Jihyun Yu <yjh0502@gmail.com>
Jim McGrath <jimmc2@gmail.com> Jim McGrath <jimmc2@gmail.com>
Jimmy Frasche <soapboxcicero@gmail.com>
Jimmy Zelinskie <jimmyzelinskie@gmail.com> Jimmy Zelinskie <jimmyzelinskie@gmail.com>
Jin-wook Jeong <jeweljar@hanmail.net> Jin-wook Jeong <jeweljar@hanmail.net>
Jingcheng Zhang <diogin@gmail.com> Jingcheng Zhang <diogin@gmail.com>
Jingguo Yao <yaojingguo@gmail.com> Jingguo Yao <yaojingguo@gmail.com>
Jiong Du <londevil@gmail.com> Jiong Du <londevil@gmail.com>
Jirka Daněk <dnk@mail.muni.cz> Jirka Daněk <dnk@mail.muni.cz>
Jiulong Wang <jiulongw@gmail.com>
Joakim Sernbrant <serbaut@gmail.com> Joakim Sernbrant <serbaut@gmail.com>
Joe Farrell <joe2farrell@gmail.com> Joe Farrell <joe2farrell@gmail.com>
Joe Harrison <joehazzers@gmail.com> Joe Harrison <joehazzers@gmail.com>
@ -545,14 +608,18 @@ Josh Goebel <dreamer3@gmail.com>
Josh Holland <jrh@joshh.co.uk> Josh Holland <jrh@joshh.co.uk>
Josh Roppo <joshroppo@gmail.com> Josh Roppo <joshroppo@gmail.com>
Joshua Chase <jcjoshuachase@gmail.com> Joshua Chase <jcjoshuachase@gmail.com>
Joshua Rubin <joshua@rubixconsulting.com>
Josselin Costanzi <josselin@costanzi.fr> Josselin Costanzi <josselin@costanzi.fr>
Jostein Stuhaug <js@solidsystem.no> Jostein Stuhaug <js@solidsystem.no>
Joyent, Inc. Joyent, Inc.
JT Olds <jtolds@xnet5.com> JT Olds <jtolds@xnet5.com>
Juan Carlos <juanjcsr@gmail.com>
Jude Pereira <judebpereira@gmail.com>
Jukka-Pekka Kekkonen <karatepekka@gmail.com> Jukka-Pekka Kekkonen <karatepekka@gmail.com>
Julian Kornberger <jk+github@digineo.de> Julian Kornberger <jk+github@digineo.de>
Julian Phillips <julian@quantumfyre.co.uk> Julian Phillips <julian@quantumfyre.co.uk>
Julien Schmidt <google@julienschmidt.com> Julien Schmidt <google@julienschmidt.com>
Junya Hayashi <ledmonster@gmail.com>
Justin Nuß <nuss.justin@gmail.com> Justin Nuß <nuss.justin@gmail.com>
Justyn Temme <justyntemme@gmail.com> Justyn Temme <justyntemme@gmail.com>
Kai Backman <kaib@golang.org> Kai Backman <kaib@golang.org>
@ -562,7 +629,9 @@ Kaleb Elwert <kelwert@atlassian.com>
Kamil Chmielewski <kamil.chm@gmail.com> Kamil Chmielewski <kamil.chm@gmail.com>
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com> Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
Kang Hu <hukangustc@gmail.com> Kang Hu <hukangustc@gmail.com>
Karel Pazdera <pazderak@gmail.com>
Karoly Negyesi <chx1975@gmail.com> Karoly Negyesi <chx1975@gmail.com>
Karsten Köhler <karsten.koehler95@gmail.com>
Kashav Madan <kshvmdn@gmail.com> Kashav Madan <kshvmdn@gmail.com>
Kate Manson <kate.manson@izettle.com> Kate Manson <kate.manson@izettle.com>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com> Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
@ -579,13 +648,17 @@ Ken Friedenbach <kenliz@cruzio.com>
Ken Rockot <ken@oz.gs> Ken Rockot <ken@oz.gs>
Ken Sedgwick <ken@bonsai.com> Ken Sedgwick <ken@bonsai.com>
Kenji Kaneda <kenji.kaneda@gmail.com> Kenji Kaneda <kenji.kaneda@gmail.com>
Kenji Yano <kenji.yano@gmail.com>
Kenneth Shaw <kenshaw@gmail.com> Kenneth Shaw <kenshaw@gmail.com>
Kenny Grant <kennygrant@gmail.com> Kenny Grant <kennygrant@gmail.com>
Kevin Ballard <kevin@sb.org> Kevin Ballard <kevin@sb.org>
Kevin Burke <kev@inburke.com> Kevin Burke <kev@inburke.com>
Kevin Kirsche <kev.kirsche@gmail.com> Kevin Kirsche <kev.kirsche@gmail.com>
Kevin Ruffin <kruffin@gmail.com>
Kevin Vu <kevin.m.vu@gmail.com> Kevin Vu <kevin.m.vu@gmail.com>
Kieran Colford <kieran@kcolford.com>
Kim Yongbin <kybinz@gmail.com> Kim Yongbin <kybinz@gmail.com>
Kirk Han <kirk91.han@gmail.com>
Klaus Post <klauspost@gmail.com> Klaus Post <klauspost@gmail.com>
Kodie Goodwin <kodiegoodwin@gmail.com> Kodie Goodwin <kodiegoodwin@gmail.com>
Koichi Shiraishi <zchee.io@gmail.com> Koichi Shiraishi <zchee.io@gmail.com>
@ -596,20 +669,26 @@ KPCompass, Inc.
Kris Nova <kris@nivenly.com> Kris Nova <kris@nivenly.com>
Kristopher Watts <traetox@gmail.com> Kristopher Watts <traetox@gmail.com>
Kun Li <likunarmstrong@gmail.com> Kun Li <likunarmstrong@gmail.com>
Kunpei Sakai <namusyaka@gmail.com>
Kyle Consalus <consalus@gmail.com> Kyle Consalus <consalus@gmail.com>
Kyle Isom <kyle@gokyle.net> Kyle Isom <kyle@gokyle.net>
Kyle Jones <kyle@kyledj.com> Kyle Jones <kyle@kyledj.com>
Kyle Lemons <kyle@kylelemons.net> Kyle Lemons <kyle@kylelemons.net>
Kyle Shannon <kyle@pobox.com>
Kyohei Kadota <lufia@lufia.org>
Kyrylo Silin <silin@kyrylo.org> Kyrylo Silin <silin@kyrylo.org>
L Campbell <unpantsu@gmail.com> L Campbell <unpantsu@gmail.com>
Lai Jiangshan <eag0628@gmail.com> Lai Jiangshan <eag0628@gmail.com>
Lakshay Garg <lakshay.garg.1996@gmail.com>
Lars Jeppesen <jeppesen.lars@gmail.com> Lars Jeppesen <jeppesen.lars@gmail.com>
Lars Wiegman <lars@namsral.com> Lars Wiegman <lars@namsral.com>
Larz Conwell <larzconwell@gmail.com> Larz Conwell <larzconwell@gmail.com>
Laurent Voisin <lpvoisin@gmail.com>
Laurie Clark-Michalek <laurie@qubit.com> Laurie Clark-Michalek <laurie@qubit.com>
LE Manh Cuong <cuong.manhle.vn@gmail.com> LE Manh Cuong <cuong.manhle.vn@gmail.com>
Lee Hinman <hinman@gmail.com> Lee Hinman <hinman@gmail.com>
Lee Packham <lpackham@gmail.com> Lee Packham <lpackham@gmail.com>
Leigh McCulloch <leighmcc@gmail.com>
Leon Klingele <git@leonklingele.de> Leon Klingele <git@leonklingele.de>
Lev Shamardin <shamardin@gmail.com> Lev Shamardin <shamardin@gmail.com>
Lewin Bormann <lewin.bormann@gmail.com> Lewin Bormann <lewin.bormann@gmail.com>
@ -629,10 +708,15 @@ Luigi Riefolo <luigi.riefolo@gmail.com>
Luit van Drongelen <luitvd@gmail.com> Luit van Drongelen <luitvd@gmail.com>
Luka Zakrajšek <tr00.g33k@gmail.com> Luka Zakrajšek <tr00.g33k@gmail.com>
Luke Curley <qpingu@gmail.com> Luke Curley <qpingu@gmail.com>
Luke Granger-Brown <git@lukegb.com>
Lyle Franklin <lylejfranklin@gmail.com>
Ma Peiqi <mapeiqi2017@gmail.com> Ma Peiqi <mapeiqi2017@gmail.com>
Maicon Costa <maiconscosta@gmail.com>
Maksym Trykur <maksym.trykur@gmail.com> Maksym Trykur <maksym.trykur@gmail.com>
Mal Curtis <mal@mal.co.nz> Mal Curtis <mal@mal.co.nz>
Manfred Touron <m@42.am> Manfred Touron <m@42.am>
Manish Goregaokar <manishsmail@gmail.com>
Mansour Rahimi <rahimi.mnr@gmail.com>
Manu S Ajith <neo@codingarena.in> Manu S Ajith <neo@codingarena.in>
Manuel Mendez <mmendez534@gmail.com> Manuel Mendez <mmendez534@gmail.com>
Marc Weistroff <marc@weistroff.net> Marc Weistroff <marc@weistroff.net>
@ -642,8 +726,11 @@ Marco Hennings <marco.hennings@freiheit.com>
Marin Bašić <marin.basic02@gmail.com> Marin Bašić <marin.basic02@gmail.com>
Mark Adams <mark@markadams.me> Mark Adams <mark@markadams.me>
Mark Bucciarelli <mkbucc@gmail.com> Mark Bucciarelli <mkbucc@gmail.com>
Mark Percival <m@mdp.im>
Mark Pulford <mark@kyne.com.au>
Mark Severson <miquella@gmail.com> Mark Severson <miquella@gmail.com>
Mark Theunissen <mark.theunissen@gmail.com> Mark Theunissen <mark.theunissen@gmail.com>
Mark Wolfe <mark@wolfe.id.au>
Marko Juhani Silokunnas <marko.silokunnas@gmail.com> Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
Marko Mudrinic <mudrinic.mare@gmail.com> Marko Mudrinic <mudrinic.mare@gmail.com>
Marko Tiikkaja <marko@joh.to> Marko Tiikkaja <marko@joh.to>
@ -661,13 +748,17 @@ Martin Neubauer <m.ne@gmx.net>
Martin Olsen <github.com@martinolsen.net> Martin Olsen <github.com@martinolsen.net>
Martin Olsson <martin@minimum.se> Martin Olsson <martin@minimum.se>
Martin Probst <martin@probst.io> Martin Probst <martin@probst.io>
Martins Sipenko <martins.sipenko@gmail.com>
Marvin Stenger <marvin.stenger94@gmail.com> Marvin Stenger <marvin.stenger94@gmail.com>
Marwan Sulaiman <marwan.sulaiman@work.co> Marwan Sulaiman <marwan.sulaiman@work.co>
Maryan Hratson <gmarik@gmail.com> Maryan Hratson <gmarik@gmail.com>
Masahiro Furudate <masahiro.furudate@gmail.com> Masahiro Furudate <masahiro.furudate@gmail.com>
Masahiro Wakame <vvakame@gmail.com> Masahiro Wakame <vvakame@gmail.com>
Masaki Yoshida <yoshida.masaki@gmail.com> Masaki Yoshida <yoshida.masaki@gmail.com>
Mat Byczkowski <mbyczkowski@gmail.com>
Máté Gulyás <mgulyas86@gmail.com> Máté Gulyás <mgulyas86@gmail.com>
Matej Baćo <matejbaco@gmail.com>
Mateus Amin <mateus.amin@gmail.com>
Mateusz Czapliński <czapkofan@gmail.com> Mateusz Czapliński <czapkofan@gmail.com>
Mathias Beke <git@denbeke.be> Mathias Beke <git@denbeke.be>
Mathias Hall-Andersen <mathias@hall-andersen.dk> Mathias Hall-Andersen <mathias@hall-andersen.dk>
@ -677,6 +768,7 @@ Mats Lidell <mats.lidell@cag.se>
Matt Aimonetti <mattaimonetti@gmail.com> Matt Aimonetti <mattaimonetti@gmail.com>
Matt Blair <me@matthewblair.net> Matt Blair <me@matthewblair.net>
Matt Bostock <matt@mattbostock.com> Matt Bostock <matt@mattbostock.com>
Matt Dee <mdee@hioscar.com>
Matt Drollette <matt@drollette.com> Matt Drollette <matt@drollette.com>
Matt Harden <matt.harden@gmail.com> Matt Harden <matt.harden@gmail.com>
Matt Jibson <matt.jibson@gmail.com> Matt Jibson <matt.jibson@gmail.com>
@ -688,23 +780,28 @@ Matt Strong <mstrong1341@gmail.com>
Matt T. Proud <matt.proud@gmail.com> Matt T. Proud <matt.proud@gmail.com>
Matt Williams <gh@mattyw.net> Matt Williams <gh@mattyw.net>
Matthew Brennan <matty.brennan@gmail.com> Matthew Brennan <matty.brennan@gmail.com>
Matthew Broberg <matthewbbroberg@gmail.com>
Matthew Cottingham <mattcottingham@gmail.com> Matthew Cottingham <mattcottingham@gmail.com>
Matthew Denton <mdenton@skyportsystems.com> Matthew Denton <mdenton@skyportsystems.com>
Matthew Holt <Matthew.Holt+git@gmail.com> Matthew Holt <Matthew.Holt+git@gmail.com>
Matthew Horsnell <matthew.horsnell@gmail.com> Matthew Horsnell <matthew.horsnell@gmail.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com> Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Matthieu Olivier <olivier.matthieu@gmail.com> Matthieu Olivier <olivier.matthieu@gmail.com>
Matthijs Kooijman <matthijs@stdin.nl>
Max Riveiro <kavu13@gmail.com> Max Riveiro <kavu13@gmail.com>
Max Schmitt <max@schmitt.mx>
Maxim Khitrov <max@mxcrypt.com> Maxim Khitrov <max@mxcrypt.com>
Maxime de Roucy <maxime.deroucy@gmail.com> Maxime de Roucy <maxime.deroucy@gmail.com>
Máximo Cuadros Ortiz <mcuadros@gmail.com> Máximo Cuadros Ortiz <mcuadros@gmail.com>
Maxwell Krohn <themax@gmail.com> Maxwell Krohn <themax@gmail.com>
Mayank Kumar <krmayankk@gmail.com>
MediaMath, Inc MediaMath, Inc
Meir Fischer <meirfischer@gmail.com> Meir Fischer <meirfischer@gmail.com>
Meng Zhuo <mengzhuo1203@gmail.com> Meng Zhuo <mengzhuo1203@gmail.com>
Meteor Development Group Meteor Development Group
Mhd Sulhan <m.shulhan@gmail.com> Mhd Sulhan <m.shulhan@gmail.com>
Micah Stetson <micah.stetson@gmail.com> Micah Stetson <micah.stetson@gmail.com>
Michael Brandenburg <mbrandenburg@bolste.com>
Michael Chaten <mchaten@gmail.com> Michael Chaten <mchaten@gmail.com>
Michael Edwards <medwards@walledcity.ca> Michael Edwards <medwards@walledcity.ca>
Michael Elkins <michael.elkins@gmail.com> Michael Elkins <michael.elkins@gmail.com>
@ -716,17 +813,22 @@ Michael Käufl <golang@c.michael-kaeufl.de>
Michael Lewis <mikelikespie@gmail.com> Michael Lewis <mikelikespie@gmail.com>
Michael MacInnis <Michael.P.MacInnis@gmail.com> Michael MacInnis <Michael.P.MacInnis@gmail.com>
Michael McConville <momcconville@gmail.com> Michael McConville <momcconville@gmail.com>
Michael McLoughlin <mmcloughlin@gmail.com>
Michael Pearson <mipearson@gmail.com> Michael Pearson <mipearson@gmail.com>
Michael Schaller <michael@5challer.de> Michael Schaller <michael@5challer.de>
Michael Schurter <michael.schurter@gmail.com>
Michael Stapelberg <michael@stapelberg.de> Michael Stapelberg <michael@stapelberg.de>
Michael Steinert <mike.steinert@gmail.com>
Michael Teichgräber <mteichgraeber@gmx.de> Michael Teichgräber <mteichgraeber@gmx.de>
Michael Vetter <g.bluehut@gmail.com> Michael Vetter <g.bluehut@gmail.com>
Michal Bohuslávek <mbohuslavek@gmail.com> Michal Bohuslávek <mbohuslavek@gmail.com>
Michał Derkacz <ziutek@lnet.pl> Michał Derkacz <ziutek@lnet.pl>
Michal Pristas <michal.pristas@gmail.com>
Miek Gieben <miek@miek.nl> Miek Gieben <miek@miek.nl>
Miguel Mendez <stxmendez@gmail.com> Miguel Mendez <stxmendez@gmail.com>
Miguel Molina <hi@mvader.me> Miguel Molina <hi@mvader.me>
Mihai Borobocea <MihaiBorobocea@gmail.com> Mihai Borobocea <MihaiBorobocea@gmail.com>
Mihail Minaev <minaev.mike@gmail.com>
Mikael Tillenius <mikti42@gmail.com> Mikael Tillenius <mikti42@gmail.com>
Mike Andrews <mra@xoba.com> Mike Andrews <mra@xoba.com>
Mike Appleby <mike@app.leby.org> Mike Appleby <mike@app.leby.org>
@ -748,9 +850,11 @@ Moriyoshi Koizumi <mozo@mozo.jp>
Morten Siebuhr <sbhr@sbhr.dk> Morten Siebuhr <sbhr@sbhr.dk>
Môshe van der Sterre <moshevds@gmail.com> Môshe van der Sterre <moshevds@gmail.com>
Mostyn Bramley-Moore <mostyn@antipode.se> Mostyn Bramley-Moore <mostyn@antipode.se>
Muhammad Falak R Wani <falakreyaz@gmail.com>
Muhammed Uluyol <uluyol0@gmail.com> Muhammed Uluyol <uluyol0@gmail.com>
Mura Li <mura_li@castech.com.tw> Mura Li <mura_li@castech.com.tw>
Nan Deng <monnand@gmail.com> Nan Deng <monnand@gmail.com>
Naoki Kanatani <k12naoki@gmail.com>
Nathan Caza <mastercactapus@gmail.com> Nathan Caza <mastercactapus@gmail.com>
Nathan Humphreys <nkhumphreys@gmail.com> Nathan Humphreys <nkhumphreys@gmail.com>
Nathan John Youngman <nj@nathany.com> Nathan John Youngman <nj@nathany.com>
@ -779,6 +883,7 @@ Nick Miyake <nmiyake@users.noreply.github.com>
Nick Patavalis <nick.patavalis@gmail.com> Nick Patavalis <nick.patavalis@gmail.com>
Nick Petroni <npetroni@cs.umd.edu> Nick Petroni <npetroni@cs.umd.edu>
Nick Robinson <nrobinson13@gmail.com> Nick Robinson <nrobinson13@gmail.com>
Nicolas BRULEZ <n.brulez@gmail.com>
Nicolas Kaiser <nikai@nikai.net> Nicolas Kaiser <nikai@nikai.net>
Nicolas Owens <mischief@offblast.org> Nicolas Owens <mischief@offblast.org>
Nicolas S. Dade <nic.dade@gmail.com> Nicolas S. Dade <nic.dade@gmail.com>
@ -788,8 +893,10 @@ Nik Nyby <nnyby@columbia.edu>
Niklas Schnelle <niklas.schnelle@gmail.com> Niklas Schnelle <niklas.schnelle@gmail.com>
Niko Dziemba <niko@dziemba.com> Niko Dziemba <niko@dziemba.com>
Nikolay Turpitko <nikolay@turpitko.com> Nikolay Turpitko <nikolay@turpitko.com>
Nils Larsgård <nilsmagnus@gmail.com>
Niranjan Godbole <niranjan8192@gmail.com> Niranjan Godbole <niranjan8192@gmail.com>
Noah Campbell <noahcampbell@gmail.com> Noah Campbell <noahcampbell@gmail.com>
Noble Johnson <noblepoly@gmail.com>
Norberto Lopes <nlopes.ml@gmail.com> Norberto Lopes <nlopes.ml@gmail.com>
Odin Ugedal <odin@ugedal.com> Odin Ugedal <odin@ugedal.com>
Oleg Bulatov <dmage@yandex-team.ru> Oleg Bulatov <dmage@yandex-team.ru>
@ -823,12 +930,15 @@ Patrick Mylund Nielsen <patrick@patrickmn.com>
Patrick Pelletier <pp.pelletier@gmail.com> Patrick Pelletier <pp.pelletier@gmail.com>
Patrick Smith <pat42smith@gmail.com> Patrick Smith <pat42smith@gmail.com>
Paul A Querna <paul.querna@gmail.com> Paul A Querna <paul.querna@gmail.com>
Paul Boyd <boyd.paul2@gmail.com>
Paul Hammond <paul@paulhammond.org> Paul Hammond <paul@paulhammond.org>
Paul Jolly <paul@myitcv.org.uk> Paul Jolly <paul@myitcv.org.uk>
Paul Lalonde <paul.a.lalonde@gmail.com> Paul Lalonde <paul.a.lalonde@gmail.com>
Paul Meyer <paul.meyer@microsoft.com> Paul Meyer <paul.meyer@microsoft.com>
Paul PISCUC <paul.piscuc@gmail.com>
Paul Querna <pquerna@apache.org> Paul Querna <pquerna@apache.org>
Paul Rosania <paul.rosania@gmail.com> Paul Rosania <paul.rosania@gmail.com>
Paul Ruest <pruest@gmail.com>
Paul Sbarra <Sbarra.Paul@gmail.com> Paul Sbarra <Sbarra.Paul@gmail.com>
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com> Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
Paul van Brouwershaven <paul@vanbrouwershaven.com> Paul van Brouwershaven <paul@vanbrouwershaven.com>
@ -853,6 +963,7 @@ Péter Szilágyi <peterke@gmail.com>
Peter Waldschmidt <peter@waldschmidt.com> Peter Waldschmidt <peter@waldschmidt.com>
Peter Waller <peter.waller@gmail.com> Peter Waller <peter.waller@gmail.com>
Peter Williams <pwil3058@gmail.com> Peter Williams <pwil3058@gmail.com>
Petrica Voicu <pvoicu@paypal.com>
Philip Børgesen <philip.borgesen@gmail.com> Philip Børgesen <philip.borgesen@gmail.com>
Philip Hofer <phofer@umich.edu> Philip Hofer <phofer@umich.edu>
Philip K. Warren <pkwarren@gmail.com> Philip K. Warren <pkwarren@gmail.com>
@ -861,26 +972,34 @@ Pierre Roullon <pierre.roullon@gmail.com>
Piers <google@hellopiers.pro> Piers <google@hellopiers.pro>
Pieter Droogendijk <pieter@binky.org.uk> Pieter Droogendijk <pieter@binky.org.uk>
Pietro Gagliardi <pietro10@mac.com> Pietro Gagliardi <pietro10@mac.com>
Pontus Leitzler <leitzler@gmail.com>
Prashant Varanasi <prashant@prashantv.com> Prashant Varanasi <prashant@prashantv.com>
Pravendra Singh <hackpravj@gmail.com> Pravendra Singh <hackpravj@gmail.com>
Preetam Jinka <pj@preet.am> Preetam Jinka <pj@preet.am>
Qiuxuan Zhu <ilsh1022@gmail.com> Qiuxuan Zhu <ilsh1022@gmail.com>
Qualcomm Data Center, Inc.
Quan Tran <qeed.quan@gmail.com> Quan Tran <qeed.quan@gmail.com>
Quan Yong Zhai <qyzhai@gmail.com> Quan Yong Zhai <qyzhai@gmail.com>
Quentin Perez <qperez@ocs.online.net> Quentin Perez <qperez@ocs.online.net>
Quentin Renard <contact@asticode.com> Quentin Renard <contact@asticode.com>
Quoc-Viet Nguyen <afelion@gmail.com> Quoc-Viet Nguyen <afelion@gmail.com>
RackTop Systems Inc. RackTop Systems Inc.
Radek Sohlich <sohlich@gmail.com>
Radu Berinde <radu@cockroachlabs.com> Radu Berinde <radu@cockroachlabs.com>
Rafal Jeczalik <rjeczalik@gmail.com> Rafal Jeczalik <rjeczalik@gmail.com>
Raif S. Naffah <go@naffah-raif.name> Raif S. Naffah <go@naffah-raif.name>
RainTank RainTank
Rajat Goel <rajat.goel2010@gmail.com> Rajat Goel <rajat.goel2010@gmail.com>
Rajath Agasthya <rajathagasthya@gmail.com>
Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
Ralph Corderoy <ralph@inputplus.co.uk> Ralph Corderoy <ralph@inputplus.co.uk>
Ramazan AYYILDIZ <rayyildiz@gmail.com>
Raphael Geronimi <raphael.geronimi@gmail.com> Raphael Geronimi <raphael.geronimi@gmail.com>
RaviTeja Pothana <ravi.tezu@gmail.com>
Ray Tung <rtung@thoughtworks.com> Ray Tung <rtung@thoughtworks.com>
Raymond Kazlauskas <raima220@gmail.com> Raymond Kazlauskas <raima220@gmail.com>
Red Hat, Inc. Red Hat, Inc.
Reilly Watson <reillywatson@gmail.com>
Reinaldo de Souza Jr <juniorz@gmail.com> Reinaldo de Souza Jr <juniorz@gmail.com>
Remi Gillig <remigillig@gmail.com> Remi Gillig <remigillig@gmail.com>
Rémy Oudompheng <oudomphe@phare.normalesup.org> Rémy Oudompheng <oudomphe@phare.normalesup.org>
@ -909,10 +1028,13 @@ Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
Roger Pau Monné <royger@gmail.com> Roger Pau Monné <royger@gmail.com>
Roger Peppe <rogpeppe@gmail.com> Roger Peppe <rogpeppe@gmail.com>
Roland Shoemaker <rolandshoemaker@gmail.com> Roland Shoemaker <rolandshoemaker@gmail.com>
Roman Budnikov <romanyx90@yandex.ru>
Ron Hashimoto <mail@h2so5.net> Ron Hashimoto <mail@h2so5.net>
Ron Minnich <rminnich@gmail.com> Ron Minnich <rminnich@gmail.com>
Ross Chater <rdchater@gmail.com>
Ross Light <rlight2@gmail.com> Ross Light <rlight2@gmail.com>
Rowan Worth <sqweek@gmail.com> Rowan Worth <sqweek@gmail.com>
Rudi Kramer <rudi.kramer@gmail.com>
Russell Haering <russellhaering@gmail.com> Russell Haering <russellhaering@gmail.com>
Ryan Bagwell <ryanbagwell@outlook.com> Ryan Bagwell <ryanbagwell@outlook.com>
Ryan Boehning <ryan.boehning@apcera.com> Ryan Boehning <ryan.boehning@apcera.com>
@ -920,6 +1042,8 @@ Ryan Hitchman <hitchmanr@gmail.com>
Ryan Lower <rpjlower@gmail.com> Ryan Lower <rpjlower@gmail.com>
Ryan Seys <ryan@ryanseys.com> Ryan Seys <ryan@ryanseys.com>
Ryan Slade <ryanslade@gmail.com> Ryan Slade <ryanslade@gmail.com>
Ryoichi KATO <ryo1kato@gmail.com>
Ryuji Iwata <qt.luigi@gmail.com>
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com> Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
S.Çağlar Onur <caglar@10ur.org> S.Çağlar Onur <caglar@10ur.org>
Sakeven Jiang <jc5930@sina.cn> Sakeven Jiang <jc5930@sina.cn>
@ -933,15 +1057,19 @@ Sascha Brawer <sascha@brawer.ch>
Sasha Sobol <sasha@scaledinference.com> Sasha Sobol <sasha@scaledinference.com>
Scott Barron <scott.barron@github.com> Scott Barron <scott.barron@github.com>
Scott Bell <scott@sctsm.com> Scott Bell <scott@sctsm.com>
Scott Crunkleton <crunk1@gmail.com>
Scott Ferguson <scottwferg@gmail.com> Scott Ferguson <scottwferg@gmail.com>
Scott Lawrence <bytbox@gmail.com> Scott Lawrence <bytbox@gmail.com>
Sean Rees <sean@erifax.org> Sean Rees <sean@erifax.org>
Sebastien Binet <seb.binet@gmail.com> Sebastien Binet <seb.binet@gmail.com>
Sébastien Paolacci <sebastien.paolacci@gmail.com> Sébastien Paolacci <sebastien.paolacci@gmail.com>
Seiji Takahashi <timaki.st@gmail.com>
Sergei Skorobogatov <skorobo@rambler.ru> Sergei Skorobogatov <skorobo@rambler.ru>
Sergey 'SnakE' Gromov <snake.scaly@gmail.com> Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
Sergey Mishin <sergeymishine@gmail.com> Sergey Mishin <sergeymishine@gmail.com>
Sergey Semin <gray12511@gmail.com>
Sergio Luis O. B. Correia <sergio@correia.cc> Sergio Luis O. B. Correia <sergio@correia.cc>
Sergiusz Bazanski <bazanski@gmail.com>
Seth Hoenig <seth.a.hoenig@gmail.com> Seth Hoenig <seth.a.hoenig@gmail.com>
Seth Vargo <sethvargo@gmail.com> Seth Vargo <sethvargo@gmail.com>
Shahar Kohanim <skohanim@gmail.com> Shahar Kohanim <skohanim@gmail.com>
@ -968,11 +1096,13 @@ Square, Inc.
Sridhar Venkatakrishnan <sridhar@laddoo.net> Sridhar Venkatakrishnan <sridhar@laddoo.net>
StalkR <stalkr@stalkr.net> StalkR <stalkr@stalkr.net>
Stan Schwertly <stan@schwertly.com> Stan Schwertly <stan@schwertly.com>
Stanislav Afanasev <php.progger@gmail.com>
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com> Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
Stéphane Travostino <stephane.travostino@gmail.com> Stéphane Travostino <stephane.travostino@gmail.com>
Stephen McQuay <stephen@mcquay.me> Stephen McQuay <stephen@mcquay.me>
Stephen Searles <stephens2424@gmail.com> Stephen Searles <stephens2424@gmail.com>
Stephen Weinberg <stephen@q5comm.com> Stephen Weinberg <stephen@q5comm.com>
Steve Gilbert <stevegilbert23@gmail.com>
Steve McCoy <mccoyst@gmail.com> Steve McCoy <mccoyst@gmail.com>
Steve Phillips <elimisteve@gmail.com> Steve Phillips <elimisteve@gmail.com>
Steve Streeting <steve@stevestreeting.com> Steve Streeting <steve@stevestreeting.com>
@ -981,46 +1111,57 @@ Steven Erenst <stevenerenst@gmail.com>
Steven Hartland <steven.hartland@multiplay.co.uk> Steven Hartland <steven.hartland@multiplay.co.uk>
Steven Wilkin <stevenwilkin@gmail.com> Steven Wilkin <stevenwilkin@gmail.com>
Stripe, Inc. Stripe, Inc.
Sukrit Handa <sukrit.handa@utoronto.ca>
Sunny <me@darkowlzz.space> Sunny <me@darkowlzz.space>
Suyash <dextrous93@gmail.com> Suyash <dextrous93@gmail.com>
Sven Almgren <sven@tras.se> Sven Almgren <sven@tras.se>
Sylvain Zimmer <sylvain@sylvainzimmer.com>
Syohei YOSHIDA <syohex@gmail.com> Syohei YOSHIDA <syohex@gmail.com>
Szabolcs Nagy <nsz@port70.net> Szabolcs Nagy <nsz@port70.net>
Tad Fisher <tadfisher@gmail.com>
Tad Glines <tad.glines@gmail.com> Tad Glines <tad.glines@gmail.com>
Taj Khattra <taj.khattra@gmail.com> Taj Khattra <taj.khattra@gmail.com>
Takeshi YAMANASHI <9.nashi@gmail.com> Takeshi YAMANASHI <9.nashi@gmail.com>
Takuya Ueda <uedatakuya@gmail.com> Takuya Ueda <uedatakuya@gmail.com>
Tal Shprecher <tshprecher@gmail.com> Tal Shprecher <tshprecher@gmail.com>
Tamir Duberstein <tamird@gmail.com> Tamir Duberstein <tamird@gmail.com>
Tao Wang <twang2218@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com> Tarmigan Casebolt <tarmigan@gmail.com>
Taro Aoki <aizu.s1230022@gmail.com> Taro Aoki <aizu.s1230022@gmail.com>
Taru Karttunen <taruti@taruti.net> Taru Karttunen <taruti@taruti.net>
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Ted Kornish <golang@tedkornish.com> Ted Kornish <golang@tedkornish.com>
Teleport Inc. Teleport Inc.
Terin Stock <terinjokes@gmail.com>
Terrel Shumway <gopher@shumway.us> Terrel Shumway <gopher@shumway.us>
Tetsuo Kiso <tetsuokiso9@gmail.com> Tetsuo Kiso <tetsuokiso9@gmail.com>
Thanatat Tamtan <acoshift@gmail.com> Thanatat Tamtan <acoshift@gmail.com>
Thiago Avelino <t@avelino.xxx>
Thiago Fransosi Farina <thiago.farina@gmail.com> Thiago Fransosi Farina <thiago.farina@gmail.com>
Thomas Alan Copeland <talan.copeland@gmail.com> Thomas Alan Copeland <talan.copeland@gmail.com>
Thomas Bonfort <thomas.bonfort@gmail.com> Thomas Bonfort <thomas.bonfort@gmail.com>
Thomas de Zeeuw <thomasdezeeuw@gmail.com> Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Thomas Desrosiers <thomasdesr@gmail.com> Thomas Desrosiers <thomasdesr@gmail.com>
Thomas Kappler <tkappler@gmail.com> Thomas Kappler <tkappler@gmail.com>
Thomas Wanielista <tomwans@gmail.com>
Thorben Krueger <thorben.krueger@gmail.com> Thorben Krueger <thorben.krueger@gmail.com>
Thordur Bjornsson <thorduri@secnorth.net> Thordur Bjornsson <thorduri@secnorth.net>
Tilman Dilo <tilman.dilo@gmail.com> Tilman Dilo <tilman.dilo@gmail.com>
Tim Cooijmans <timcooijmans@gmail.com> Tim Cooijmans <timcooijmans@gmail.com>
Tim Cooper <tim.cooper@layeh.com>
Tim Ebringer <tim.ebringer@gmail.com> Tim Ebringer <tim.ebringer@gmail.com>
Tim Heckman <t@heckman.io> Tim Heckman <t@heckman.io>
Tim Henderson <tim.tadh@gmail.com> Tim Henderson <tim.tadh@gmail.com>
Tim Wright <tenortim@gmail.com>
Timo Savola <timo.savola@gmail.com> Timo Savola <timo.savola@gmail.com>
Timo Truyts <alkaloid.btx@gmail.com> Timo Truyts <alkaloid.btx@gmail.com>
Timothy Studd <tim@timstudd.com> Timothy Studd <tim@timstudd.com>
Tobias Assarsson <tobias.assarsson@gmail.com>
Tobias Columbus <tobias.columbus@gmail.com> Tobias Columbus <tobias.columbus@gmail.com>
Tobias Klauser <tklauser@distanz.ch> Tobias Klauser <tklauser@distanz.ch>
Todd Neal <todd@tneal.org> Todd Neal <todd@tneal.org>
Tom Heng <zhm20070928@gmail.com> Tom Heng <zhm20070928@gmail.com>
Tom Levy <tomlevy93@gmail.com>
Tom Linford <tomlinford@gmail.com> Tom Linford <tomlinford@gmail.com>
Tommy Schaefer <tommy.schaefer@teecom.com> Tommy Schaefer <tommy.schaefer@teecom.com>
Tonis Tiigi <tonistiigi@gmail.com> Tonis Tiigi <tonistiigi@gmail.com>
@ -1035,8 +1176,10 @@ Trey Roessig <trey.roessig@gmail.com>
Trey Tacon <ttacon@gmail.com> Trey Tacon <ttacon@gmail.com>
Tristan Colgate <tcolgate@gmail.com> Tristan Colgate <tcolgate@gmail.com>
Tristan Ooohry <ooohry@gmail.com> Tristan Ooohry <ooohry@gmail.com>
Troels Thomsen <troels@thomsen.io>
Trung Nguyen <trung.n.k@gmail.com> Trung Nguyen <trung.n.k@gmail.com>
Tudor Golubenco <tudor.g@gmail.com> Tudor Golubenco <tudor.g@gmail.com>
Tugdual Saunier <tugdual.saunier@gmail.com>
Tuo Shan <sturbo89@gmail.com> Tuo Shan <sturbo89@gmail.com>
Tyler Bunnell <tylerbunnell@gmail.com> Tyler Bunnell <tylerbunnell@gmail.com>
Tyler Treat <ttreat31@gmail.com> Tyler Treat <ttreat31@gmail.com>
@ -1063,14 +1206,18 @@ Volker Dobler <dr.volker.dobler@gmail.com>
Wade Simmons <wade@wades.im> Wade Simmons <wade@wades.im>
Wander Lairson Costa <wcosta@mozilla.com> Wander Lairson Costa <wcosta@mozilla.com>
Weaveworks Weaveworks
Wèi Cōngruì <crvv.mail@gmail.com>
Wei Guangjing <vcc.163@gmail.com> Wei Guangjing <vcc.163@gmail.com>
Weichao Tang <tevic.tt@gmail.com> Weichao Tang <tevic.tt@gmail.com>
Wembley G. Leach, Jr <wembley.gl@gmail.com>
Will Faught <will.faught@gmail.com>
Will Storey <will@summercat.com> Will Storey <will@summercat.com>
Willem van der Schyff <willemvds@gmail.com> Willem van der Schyff <willemvds@gmail.com>
William Josephson <wjosephson@gmail.com> William Josephson <wjosephson@gmail.com>
William Orr <will@worrbase.com> <ay1244@gmail.com> William Orr <will@worrbase.com> <ay1244@gmail.com>
Wisdom Omuya <deafgoat@gmail.com> Wisdom Omuya <deafgoat@gmail.com>
Wu Yunzhou <yunzhouwu@gmail.com> Wu Yunzhou <yunzhouwu@gmail.com>
Xi Ruoyao <xry23333@gmail.com>
Xia Bin <snyh@snyh.org> Xia Bin <snyh@snyh.org>
Xing Xing <mikespook@gmail.com> Xing Xing <mikespook@gmail.com>
Xu Fei <badgangkiller@gmail.com> Xu Fei <badgangkiller@gmail.com>
@ -1078,30 +1225,36 @@ Xudong Zhang <felixmelon@gmail.com>
Xuyang Kang <xuyangkang@gmail.com> Xuyang Kang <xuyangkang@gmail.com>
Yahoo Inc. Yahoo Inc.
Yann Kerhervé <yann.kerherve@gmail.com> Yann Kerhervé <yann.kerherve@gmail.com>
Yann Salaün <yannsalaun1@gmail.com>
Yao Zhang <lunaria21@gmail.com> Yao Zhang <lunaria21@gmail.com>
Yasha Bubnov <girokompass@gmail.com> Yasha Bubnov <girokompass@gmail.com>
Yasuharu Goto <matope.ono@gmail.com> Yasuharu Goto <matope.ono@gmail.com>
Yasuhiro Matsumoto <mattn.jp@gmail.com> Yasuhiro Matsumoto <mattn.jp@gmail.com>
Yestin Sun <ylh@pdx.edu> Yestin Sun <ylh@pdx.edu>
Yesudeep Mangalapilly <yesudeep@google.com>
Yissakhar Z. Beck <yissakhar.beck@gmail.com> Yissakhar Z. Beck <yissakhar.beck@gmail.com>
Yo-An Lin <yoanlin93@gmail.com> Yo-An Lin <yoanlin93@gmail.com>
Yongjian Xu <i3dmaster@gmail.com> Yongjian Xu <i3dmaster@gmail.com>
Yorman Arias <cixtords@gmail.com> Yorman Arias <cixtords@gmail.com>
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp> Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
Yukihiro Nishinaka <6elpinal@gmail.com>
Yusuke Kagiwada <block.rxckin.beats@gmail.com> Yusuke Kagiwada <block.rxckin.beats@gmail.com>
Yuusei Kuwana <kuwana@kumama.org> Yuusei Kuwana <kuwana@kumama.org>
Yuval Pavel Zholkover <paulzhol@gmail.com> Yuval Pavel Zholkover <paulzhol@gmail.com>
Zac Bergquist <zbergquist99@gmail.com> Zac Bergquist <zbergquist99@gmail.com>
Zach Bintliff <zbintliff@gmail.com> Zach Bintliff <zbintliff@gmail.com>
Zach Gershman <zachgersh@gmail.com>
Zak <zrjknill@gmail.com> Zak <zrjknill@gmail.com>
Zakatell Kanda <hi@zkanda.io> Zakatell Kanda <hi@zkanda.io>
Zellyn Hunter <zellyn@gmail.com> Zellyn Hunter <zellyn@gmail.com>
Zemanta d.o.o. Zemanta d.o.o.
Zev Goldstein <zev.goldstein@gmail.com> Zev Goldstein <zev.goldstein@gmail.com>
Zhongtao Chen <chenzhongtao@126.com>
Ziad Hatahet <hatahet@gmail.com> Ziad Hatahet <hatahet@gmail.com>
Zorion Arrizabalaga <zorionk@gmail.com> Zorion Arrizabalaga <zorionk@gmail.com>
Максим Федосеев <max.faceless.frei@gmail.com> Максим Федосеев <max.faceless.frei@gmail.com>
Роман Хавроненко <hagen1778@gmail.com>
Тарас Буник <tbunyk@gmail.com>
Фахриддин Балтаев <faxriddinjon@gmail.com> Фахриддин Балтаев <faxriddinjon@gmail.com>
张嵩 <zs349596@gmail.com> 张嵩 <zs349596@gmail.com>
申习之 <bronze1man@gmail.com> 申习之 <bronze1man@gmail.com>

View file

@ -30,11 +30,6 @@ For change proposals, see [Proposing Changes To Go](https://github.com/golang/pr
Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches. Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) before sending patches.
**We do not accept GitHub pull requests**
(we use [an instance](https://go-review.googlesource.com/) of the
[Gerrit](https://www.gerritcodereview.com/) code review system instead).
Also, please do not post patches on the issue tracker.
Unless otherwise noted, the Go source files are distributed under Unless otherwise noted, the Go source files are distributed under
the BSD-style license found in the LICENSE file. the BSD-style license found in the LICENSE file.

View file

@ -44,13 +44,18 @@ Adam Bender <abender@google.com>
Adam Eijdenberg <adam@continusec.com> Adam Eijdenberg <adam@continusec.com>
Adam Kisala <adam.kisala@gmail.com> Adam Kisala <adam.kisala@gmail.com>
Adam Langley <agl@golang.org> Adam Langley <agl@golang.org>
Adam Thomason <athomason@gmail.com>
Aditya Mukerjee <dev@chimeracoder.net> Aditya Mukerjee <dev@chimeracoder.net>
Adrian Hesketh <adrianhesketh@hushmail.com>
Adrian Nos <nos.adrian@gmail.com> Adrian Nos <nos.adrian@gmail.com>
Adrian O'Grady <elpollouk@gmail.com> Adrian O'Grady <elpollouk@gmail.com>
Adrien Bustany <adrien-xx-google@bustany.org> Adrien Bustany <adrien-xx-google@bustany.org>
Aécio Júnior <aeciodantasjunior@gmail.com> Aécio Júnior <aeciodantasjunior@gmail.com>
Aeneas Rekkas (arekkas) <aeneas@ory.am>
Afanasev Stanislav <phpprogger@gmail.com>
Agis Anastasopoulos <agis.anast@gmail.com> Agis Anastasopoulos <agis.anast@gmail.com>
Ahmed Waheed Moanes <oneofone@gmail.com> Agniva De Sarker <agnivade@yahoo.co.in>
Ahmed Wahed <oneofone@gmail.com>
Ahmet Alp Balkan <ahmetb@google.com> Ahmet Alp Balkan <ahmetb@google.com>
Ahmy Yulrizka <yulrizka@gmail.com> Ahmy Yulrizka <yulrizka@gmail.com>
Aiden Scandella <ai@uber.com> Aiden Scandella <ai@uber.com>
@ -90,6 +95,7 @@ Alexander Menzhinsky <amenzhinsky@gmail.com>
Alexander Morozov <lk4d4math@gmail.com> Alexander Morozov <lk4d4math@gmail.com>
Alexander Neumann <alexander@bumpern.de> Alexander Neumann <alexander@bumpern.de>
Alexander Orlov <alexander.orlov@loxal.net> Alexander Orlov <alexander.orlov@loxal.net>
Alexander Pantyukhin <apantykhin@gmail.com>
Alexander Polcyn <apolcyn@google.com> Alexander Polcyn <apolcyn@google.com>
Alexander Reece <awreece@gmail.com> Alexander Reece <awreece@gmail.com>
Alexander Surma <surma@surmair.de> Alexander Surma <surma@surmair.de>
@ -98,6 +104,7 @@ Alexander Zolotov <goldifit@gmail.com>
Alexandre Cesaro <alexandre.cesaro@gmail.com> Alexandre Cesaro <alexandre.cesaro@gmail.com>
Alexandre Fiori <fiorix@gmail.com> Alexandre Fiori <fiorix@gmail.com>
Alexandre Normand <alexandre.normand@gmail.com> Alexandre Normand <alexandre.normand@gmail.com>
Alexandre Parentea <aubonbeurre@gmail.com>
Alexandru Moșoi <brtzsnr@gmail.com> Alexandru Moșoi <brtzsnr@gmail.com>
Alexei Sholik <alcosholik@gmail.com> Alexei Sholik <alcosholik@gmail.com>
Alexey Borzenkov <snaury@gmail.com> Alexey Borzenkov <snaury@gmail.com>
@ -110,8 +117,10 @@ Aliaksandr Valialkin <valyala@gmail.com>
Alif Rachmawadi <subosito@gmail.com> Alif Rachmawadi <subosito@gmail.com>
Allan Simon <allan.simon@supinfo.com> Allan Simon <allan.simon@supinfo.com>
Alok Menghrajani <alok.menghrajani@gmail.com> Alok Menghrajani <alok.menghrajani@gmail.com>
Aman Gupta <aman@tmm1.net>
Amir Mohammad Saied <amir@gluegadget.com> Amir Mohammad Saied <amir@gluegadget.com>
Amrut Joshi <amrut.joshi@gmail.com> Amrut Joshi <amrut.joshi@gmail.com>
Anand K. Mistry <anand@mistry.ninja>
Anders Pearson <anders@columbia.edu> Anders Pearson <anders@columbia.edu>
André Carvalho <asantostc@gmail.com> André Carvalho <asantostc@gmail.com>
Andre Nathan <andrenth@gmail.com> Andre Nathan <andrenth@gmail.com>
@ -144,7 +153,10 @@ Andrew Wilkins <axwalk@gmail.com>
Andrew Williams <williams.andrew@gmail.com> Andrew Williams <williams.andrew@gmail.com>
Andrey Mirtchovski <mirtchovski@gmail.com> Andrey Mirtchovski <mirtchovski@gmail.com>
Andrey Petrov <andrey.petrov@shazow.net> Andrey Petrov <andrey.petrov@shazow.net>
Andrii Soldatenko <andrii.soldatenko@gmail.com>
Andrii Soluk <isoluchok@gmail.com>
Andriy Lytvynov <lytvynov.a.v@gmail.com> Andriy Lytvynov <lytvynov.a.v@gmail.com>
Andrzej Żeżel <andrii.zhezhel@gmail.com>
Andy Balholm <andy@balholm.com> Andy Balholm <andy@balholm.com>
Andy Davis <andy@bigandian.com> Andy Davis <andy@bigandian.com>
Andy Finkenstadt <afinkenstadt@zynga.com> Andy Finkenstadt <afinkenstadt@zynga.com>
@ -155,9 +167,11 @@ Angelo Bulfone <mbulfone@gmail.com>
Anh Hai Trinh <anh.hai.trinh@gmail.com> Anh Hai Trinh <anh.hai.trinh@gmail.com>
Anmol Sethi <anmol@aubble.com> Anmol Sethi <anmol@aubble.com>
Anschel Schaffer-Cohen <anschelsc@gmail.com> Anschel Schaffer-Cohen <anschelsc@gmail.com>
Anthony Alves <cvballa3g0@gmail.com>
Anthony Canino <anthony.canino1@gmail.com> Anthony Canino <anthony.canino1@gmail.com>
Anthony Eufemio <anthony.eufemio@gmail.com> Anthony Eufemio <anthony.eufemio@gmail.com>
Anthony Martin <ality@pbrane.org> Anthony Martin <ality@pbrane.org>
Anthony Sottile <asottile@umich.edu>
Anthony Starks <ajstarks@gmail.com> Anthony Starks <ajstarks@gmail.com>
Anthony Voutas <voutasaurus@gmail.com> Anthony Voutas <voutasaurus@gmail.com>
Anthony Woods <awoods@raintank.io> Anthony Woods <awoods@raintank.io>
@ -168,6 +182,7 @@ Antonio Troina <thoeni@gmail.com>
Apisak Darakananda <pongad@gmail.com> Apisak Darakananda <pongad@gmail.com>
Aram Hăvărneanu <aram@mgk.ro> Aram Hăvărneanu <aram@mgk.ro>
Areski Belaid <areski@gmail.com> Areski Belaid <areski@gmail.com>
Ariel Mashraki <ariel@mashraki.co.il>
Arkadi Pyuro <arkadi@google.com> Arkadi Pyuro <arkadi@google.com>
Arlo Breault <arlolra@gmail.com> Arlo Breault <arlolra@gmail.com>
Arnaud Ysmal <arnaud.ysmal@gmail.com> Arnaud Ysmal <arnaud.ysmal@gmail.com>
@ -185,6 +200,7 @@ Aulus Egnatius Varialus <varialus@gmail.com>
Austin Clements <austin@google.com> <aclements@csail.mit.edu> Austin Clements <austin@google.com> <aclements@csail.mit.edu>
awaw fumin <awawfumin@gmail.com> awaw fumin <awawfumin@gmail.com>
Awn Umar <awn@cryptolosophy.io> Awn Umar <awn@cryptolosophy.io>
Axel Wagner <axel.wagner.hh@googlemail.com>
Ayanamist Yang <ayanamist@gmail.com> Ayanamist Yang <ayanamist@gmail.com>
Aymerick Jéhanne <aymerick@jehanne.org> Aymerick Jéhanne <aymerick@jehanne.org>
Baiju Muthukadan <baiju.m.mail@gmail.com> Baiju Muthukadan <baiju.m.mail@gmail.com>
@ -194,9 +210,12 @@ Bastian Ike <bastian.ike@gmail.com>
Ben Burkert <ben@benburkert.com> Ben Burkert <ben@benburkert.com>
Ben Eitzen <eitzenb@golang.org> Ben Eitzen <eitzenb@golang.org>
Ben Fried <ben.fried@gmail.com> Ben Fried <ben.fried@gmail.com>
Ben Haines <bhainesva@gmail.com>
Ben Laurie <ben@links.org> <benl@google.com>
Ben Lubar <ben.lubar@gmail.com> Ben Lubar <ben.lubar@gmail.com>
Ben Lynn <benlynn@gmail.com> Ben Lynn <benlynn@gmail.com>
Ben Olive <sionide21@gmail.com> Ben Olive <sionide21@gmail.com>
Ben Schwartz <bemasc@google.com>
Ben Shi <powerman1st@163.com> Ben Shi <powerman1st@163.com>
Benjamin Black <b@b3k.us> Benjamin Black <b@b3k.us>
Benjamin Prosnitz <bprosnitz@google.com> Benjamin Prosnitz <bprosnitz@google.com>
@ -212,11 +231,15 @@ Billie Harold Cleek <bhcleek@gmail.com>
Billy Lynch <wlynch@google.com> Billy Lynch <wlynch@google.com>
Bjorn Tillenius <bjorn@tillenius.me> Bjorn Tillenius <bjorn@tillenius.me>
Bjorn Tipling <bjorn.tipling@gmail.com> Bjorn Tipling <bjorn.tipling@gmail.com>
Blain Smith <rebelgeek@blainsmith.com>
Blake Gentry <blakesgentry@gmail.com> Blake Gentry <blakesgentry@gmail.com>
Blake Mesdag <blakemesdag@gmail.com>
Blake Mizerany <blake.mizerany@gmail.com> Blake Mizerany <blake.mizerany@gmail.com>
Blixt <me@blixt.nyc> Blixt <me@blixt.nyc>
Bobby Powers <bobbypowers@gmail.com> Bobby Powers <bobbypowers@gmail.com>
Boris Nagaev <nagaev@google.com> Boris Nagaev <nagaev@google.com>
Borja Clemente <borja.clemente@gmail.com>
Brad Burch <brad.burch@gmail.com>
Brad Fitzpatrick <bradfitz@golang.org> <bradfitz@gmail.com> Brad Fitzpatrick <bradfitz@golang.org> <bradfitz@gmail.com>
Brad Garcia <bgarcia@golang.org> Brad Garcia <bgarcia@golang.org>
Brad Jones <rbjones@google.com> Brad Jones <rbjones@google.com>
@ -229,11 +252,13 @@ Brandon Gilmore <varz@google.com>
Brendan Daniel Tracey <tracey.brendan@gmail.com> Brendan Daniel Tracey <tracey.brendan@gmail.com>
Brendan O'Dea <bod@golang.org> Brendan O'Dea <bod@golang.org>
Brett Cannon <bcannon@gmail.com> Brett Cannon <bcannon@gmail.com>
Brett Merrill <brett.j.merrill94@gmail.com>
Brian Dellisanti <briandellisanti@gmail.com> Brian Dellisanti <briandellisanti@gmail.com>
Brian Downs <brian.downs@gmail.com> Brian Downs <brian.downs@gmail.com>
Brian G. Merrell <bgmerrell@gmail.com> Brian G. Merrell <bgmerrell@gmail.com>
Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com> Brian Gitonga Marete <marete@toshnix.com> <bgmarete@gmail.com> <bgm@google.com>
Brian Kennedy <btkennedy@gmail.com> Brian Kennedy <btkennedy@gmail.com>
Brian Kessler <brian.m.kessler@gmail.com>
Brian Ketelsen <bketelsen@gmail.com> Brian Ketelsen <bketelsen@gmail.com>
Brian Slesinsky <skybrian@google.com> Brian Slesinsky <skybrian@google.com>
Brian Smith <ohohvi@gmail.com> Brian Smith <ohohvi@gmail.com>
@ -243,6 +268,7 @@ Bryan C. Mills <bcmills@google.com>
Bryan Chan <bryan.chan@ca.ibm.com> Bryan Chan <bryan.chan@ca.ibm.com>
Bryan Ford <brynosaurus@gmail.com> Bryan Ford <brynosaurus@gmail.com>
Bulat Gaifullin <gaifullinbf@gmail.com> Bulat Gaifullin <gaifullinbf@gmail.com>
Burak Guven <bguven@gmail.com>
Caine Tighe <arctanofyourface@gmail.com> Caine Tighe <arctanofyourface@gmail.com>
Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com> Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Caleb Spare <cespare@gmail.com> Caleb Spare <cespare@gmail.com>
@ -266,11 +292,14 @@ Catalin Patulea <catalinp@google.com>
Cedric Staub <cs@squareup.com> Cedric Staub <cs@squareup.com>
Cezar Sá Espinola <cezarsa@gmail.com> Cezar Sá Espinola <cezarsa@gmail.com>
ChaiShushan <chaishushan@gmail.com> ChaiShushan <chaishushan@gmail.com>
Charles Fenwick Elliott <Charles@FenwickElliott.io>
Charles L. Dorian <cldorian@gmail.com> Charles L. Dorian <cldorian@gmail.com>
Charles Lee <zombie.fml@gmail.com> Charles Lee <zombie.fml@gmail.com>
Charles Weill <weill@google.com> Charles Weill <weill@google.com>
Cherry Zhang <cherryyz@google.com> Cherry Zhang <cherryyz@google.com>
Chew Choon Keat <choonkeat@gmail.com> Chew Choon Keat <choonkeat@gmail.com>
Cholerae Hu <choleraehyq@gmail.com>
Chris Ball <chris@printf.net>
Chris Biscardi <chris@christopherbiscardi.com> Chris Biscardi <chris@christopherbiscardi.com>
Chris Broadfoot <cbro@golang.org> Chris Broadfoot <cbro@golang.org>
Chris Dollin <ehog.hedge@gmail.com> Chris Dollin <ehog.hedge@gmail.com>
@ -287,6 +316,7 @@ Chris Raynor <raynor@google.com>
Chris Roche <rodaine@gmail.com> Chris Roche <rodaine@gmail.com>
Chris Stockton <chrisstocktonaz@gmail.com> Chris Stockton <chrisstocktonaz@gmail.com>
Chris Zou <chriszou@ca.ibm.com> Chris Zou <chriszou@ca.ibm.com>
Christian Alexander <christian@linux.com>
Christian Couder <chriscool@tuxfamily.org> Christian Couder <chriscool@tuxfamily.org>
Christian Himpel <chressie@googlemail.com> <chressie@gmail.com> Christian Himpel <chressie@googlemail.com> <chressie@gmail.com>
Christine Hansmann <chhansmann@gmail.com> Christine Hansmann <chhansmann@gmail.com>
@ -294,11 +324,14 @@ Christoffer Buchholz <christoffer.buchholz@gmail.com>
Christoph Hack <christoph@tux21b.org> Christoph Hack <christoph@tux21b.org>
Christopher Cahoon <chris.cahoon@gmail.com> Christopher Cahoon <chris.cahoon@gmail.com>
Christopher Guiney <chris@guiney.net> Christopher Guiney <chris@guiney.net>
Christopher Henderson <chris@chenderson.org>
Christopher Koch <chrisko@google.com>
Christopher Nelson <nadiasvertex@gmail.com> Christopher Nelson <nadiasvertex@gmail.com>
Christopher Nielsen <m4dh4tt3r@gmail.com> Christopher Nielsen <m4dh4tt3r@gmail.com>
Christopher Redden <christopher.redden@gmail.com> Christopher Redden <christopher.redden@gmail.com>
Christopher Swenson <cswenson@google.com> Christopher Swenson <cswenson@google.com>
Christopher Wedgwood <cw@f00f.org> Christopher Wedgwood <cw@f00f.org>
Christos Zoulas <christos@zoulas.com> <zoulasc@gmail.com>
Christy Perez <christy@linux.vnet.ibm.com> Christy Perez <christy@linux.vnet.ibm.com>
CL Sung <clsung@gmail.com> <cl_sung@htc.com> CL Sung <clsung@gmail.com> <cl_sung@htc.com>
Clement Skau <clementskau@gmail.com> Clement Skau <clementskau@gmail.com>
@ -341,6 +374,8 @@ Daniel Skinner <daniel@dasa.cc>
Daniel Speichert <daniel@speichert.pl> Daniel Speichert <daniel@speichert.pl>
Daniel Theophanes <kardianos@gmail.com> Daniel Theophanes <kardianos@gmail.com>
Daniel Upton <daniel@floppy.co> Daniel Upton <daniel@floppy.co>
Daniela Petruzalek <daniela.petruzalek@gmail.com>
Danny Rosseau <daniel.rosseau@gmail.com>
Daria Kolistratova <daria.kolistratova@intel.com> Daria Kolistratova <daria.kolistratova@intel.com>
Darren Elwood <darren@textnode.com> Darren Elwood <darren@textnode.com>
Datong Sun <dndx@idndx.com> Datong Sun <dndx@idndx.com>
@ -379,6 +414,7 @@ David Thomas <davidthomas426@gmail.com>
David Titarenco <david.titarenco@gmail.com> David Titarenco <david.titarenco@gmail.com>
David Volquartz Lebech <david@lebech.info> David Volquartz Lebech <david@lebech.info>
Davies Liu <davies.liu@gmail.com> Davies Liu <davies.liu@gmail.com>
Davor Kapsa <davor.kapsa@gmail.com>
Dean Prichard <dean.prichard@gmail.com> Dean Prichard <dean.prichard@gmail.com>
Deepak Jois <deepak.jois@gmail.com> Deepak Jois <deepak.jois@gmail.com>
Denis Bernard <db047h@gmail.com> Denis Bernard <db047h@gmail.com>
@ -425,15 +461,19 @@ Dustin Sallings <dsallings@gmail.com>
Dustin Shields-Cloues <dcloues@gmail.com> Dustin Shields-Cloues <dcloues@gmail.com>
Dvir Volk <dvir@everything.me> <dvirsky@gmail.com> Dvir Volk <dvir@everything.me> <dvirsky@gmail.com>
Dylan Waits <dylan@waits.io> Dylan Waits <dylan@waits.io>
Edan Bedrik <3d4nb3@gmail.com>
Eden Li <eden.li@gmail.com> Eden Li <eden.li@gmail.com>
Edward Muller <edwardam@interlix.com> Edward Muller <edwardam@interlix.com>
Egon Elbre <egonelbre@gmail.com> Egon Elbre <egonelbre@gmail.com>
Ehren Kret <ehren.kret@gmail.com> Ehren Kret <ehren.kret@gmail.com>
Eitan Adler <lists@eitanadler.com> Eitan Adler <lists@eitanadler.com>
Eivind Uggedal <eivind@uggedal.com> Eivind Uggedal <eivind@uggedal.com>
Elbert Fliek <efliek@gmail.com>
Elena Grahovac <elena@grahovac.me>
Elias Naur <elias.naur@gmail.com> Elias Naur <elias.naur@gmail.com>
Elliot Morrison-Reed <elliotmr@gmail.com> Elliot Morrison-Reed <elliotmr@gmail.com>
Emil Hessman <c.emil.hessman@gmail.com> <emil@hessman.se> Emerson Lin <linyintor@gmail.com>
Emil Hessman <emil@hessman.se>
Emilien Kenler <hello@emilienkenler.com> Emilien Kenler <hello@emilienkenler.com>
Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca> Emmanuel Odeke <emm.odeke@gmail.com> <odeke@ualberta.ca>
Eoghan Sherry <ejsherry@gmail.com> Eoghan Sherry <ejsherry@gmail.com>
@ -444,6 +484,7 @@ Eric Garrido <ekg@google.com>
Eric Koleda <ekoleda+devrel@google.com> Eric Koleda <ekoleda+devrel@google.com>
Eric Lagergren <ericscottlagergren@gmail.com> Eric Lagergren <ericscottlagergren@gmail.com>
Eric Milliken <emilliken@gmail.com> Eric Milliken <emilliken@gmail.com>
Eric Rescorla <ekr@rtfm.com>
Eric Roshan-Eisner <eric.d.eisner@gmail.com> Eric Roshan-Eisner <eric.d.eisner@gmail.com>
Erik Aigner <aigner.erik@gmail.com> Erik Aigner <aigner.erik@gmail.com>
Erik Dubbelboer <erik@dubbelboer.com> Erik Dubbelboer <erik@dubbelboer.com>
@ -458,6 +499,7 @@ Euan Kemp <euank@euank.com>
Evan Broder <evan@stripe.com> Evan Broder <evan@stripe.com>
Evan Brown <evanbrown@google.com> Evan Brown <evanbrown@google.com>
Evan Hicks <evan.hicks2@gmail.com> Evan Hicks <evan.hicks2@gmail.com>
Evan Jones <ej@evanjones.ca>
Evan Kroske <evankroske@google.com> Evan Kroske <evankroske@google.com>
Evan Martin <evan.martin@gmail.com> Evan Martin <evan.martin@gmail.com>
Evan Phoenix <evan@phx.io> Evan Phoenix <evan@phx.io>
@ -481,7 +523,7 @@ Fedor Indutny <fedor@indutny.com>
Felipe Oliveira <felipeweb.programador@gmail.com> Felipe Oliveira <felipeweb.programador@gmail.com>
Felix Geisendörfer <haimuiba@gmail.com> Felix Geisendörfer <haimuiba@gmail.com>
Filip Gruszczyński <gruszczy@gmail.com> Filip Gruszczyński <gruszczy@gmail.com>
Filippo Valsorda <filippo@cloudflare.com> <hi@filippo.io> Filippo Valsorda <filippo@golang.org> <filippo@cloudflare.com> <hi@filippo.io>
Firmansyah Adiputra <frm.adiputra@gmail.com> Firmansyah Adiputra <frm.adiputra@gmail.com>
Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de> Florian Uekermann <florian@uekermann-online.de> <f1@uekermann-online.de>
Florian Weimer <fw@deneb.enyo.de> Florian Weimer <fw@deneb.enyo.de>
@ -492,6 +534,8 @@ Francesc Campoy <campoy@golang.org>
Francisco Claude <fclaude@recoded.cl> Francisco Claude <fclaude@recoded.cl>
Francisco Rojas <francisco.rojas.gallegos@gmail.com> Francisco Rojas <francisco.rojas.gallegos@gmail.com>
Francisco Souza <franciscossouza@gmail.com> Francisco Souza <franciscossouza@gmail.com>
Frank Somers <fsomers@arista.com>
Frederic Guillot <frederic.guillot@gmail.com>
Frederick Kelly Mayle III <frederickmayle@gmail.com> Frederick Kelly Mayle III <frederickmayle@gmail.com>
Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com> Fredrik Enestad <fredrik.enestad@soundtrackyourbrand.com>
Fredrik Forsmo <fredrik.forsmo@gmail.com> Fredrik Forsmo <fredrik.forsmo@gmail.com>
@ -504,6 +548,7 @@ Gabriel Aszalos <gabriel.aszalos@gmail.com>
Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com> Gabriel Nicolas Avellaneda <avellaneda.gabriel@gmail.com>
Gabriel Russell <gabriel.russell@gmail.com> Gabriel Russell <gabriel.russell@gmail.com>
Gareth Paul Jones <gpj@foursquare.com> Gareth Paul Jones <gpj@foursquare.com>
Garret Kelly <gdk@google.com>
Garrick Evans <garrick@google.com> Garrick Evans <garrick@google.com>
Gary Burd <gary@beagledreams.com> <gary.burd@gmail.com> Gary Burd <gary@beagledreams.com> <gary.burd@gmail.com>
Gary Elliott <garyelliott@google.com> Gary Elliott <garyelliott@google.com>
@ -511,6 +556,7 @@ Gaurish Sharma <contact@gaurishsharma.com>
Gautham Thambidorai <gautham.dorai@gmail.com> Gautham Thambidorai <gautham.dorai@gmail.com>
Geert-Johan Riemer <gjr19912@gmail.com> Geert-Johan Riemer <gjr19912@gmail.com>
Gengliang Wang <ltnwgl@gmail.com> Gengliang Wang <ltnwgl@gmail.com>
Geoff Berry <gberry.qdt@qualcommdatacenter.com>
Geoffroy Lorieux <lorieux.g@gmail.com> Geoffroy Lorieux <lorieux.g@gmail.com>
Georg Reinke <guelfey@gmail.com> Georg Reinke <guelfey@gmail.com>
George Gkirtsou <ggirtsou@gmail.com> George Gkirtsou <ggirtsou@gmail.com>
@ -526,9 +572,12 @@ Glenn Lewis <gmlewis@google.com>
Gordon Klaus <gordon.klaus@gmail.com> Gordon Klaus <gordon.klaus@gmail.com>
Graham King <graham4king@gmail.com> Graham King <graham4king@gmail.com>
Graham Miller <graham.miller@gmail.com> Graham Miller <graham.miller@gmail.com>
Grant Griffiths <ggp493@gmail.com>
Greg Poirier <greg.istehbest@gmail.com> Greg Poirier <greg.istehbest@gmail.com>
Greg Ward <greg@gerg.ca> Greg Ward <greg@gerg.ca>
Gregory Man <man.gregory@gmail.com> Gregory Man <man.gregory@gmail.com>
Guilherme Garnier <guilherme.garnier@gmail.com>
Guilherme Rezende <guilhermebr@gmail.com>
Guillaume J. Charmes <guillaume@charmes.net> Guillaume J. Charmes <guillaume@charmes.net>
Guobiao Mei <meiguobiao@gmail.com> Guobiao Mei <meiguobiao@gmail.com>
Gustav Paul <gustav.paul@gmail.com> Gustav Paul <gustav.paul@gmail.com>
@ -542,6 +591,7 @@ Hajime Hoshi <hajimehoshi@gmail.com>
Hallgrimur Gunnarsson <halg@google.com> Hallgrimur Gunnarsson <halg@google.com>
Han-Wen Nienhuys <hanwen@google.com> Han-Wen Nienhuys <hanwen@google.com>
Hang Qian <hangqian90@gmail.com> Hang Qian <hangqian90@gmail.com>
Hanjun Kim <hallazzang@gmail.com>
Hari haran <hariharan.uno@gmail.com> Hari haran <hariharan.uno@gmail.com>
Hariharan Srinath <srinathh@gmail.com> Hariharan Srinath <srinathh@gmail.com>
Harley Laue <losinggeneration@gmail.com> Harley Laue <losinggeneration@gmail.com>
@ -554,9 +604,14 @@ Hector Martin Cantero <hector@marcansoft.com>
Henning Schmiedehausen <henning@schmiedehausen.org> Henning Schmiedehausen <henning@schmiedehausen.org>
Henrik Edwards <henrik.edwards@gmail.com> Henrik Edwards <henrik.edwards@gmail.com>
Henrik Hodne <henrik@hodne.io> Henrik Hodne <henrik@hodne.io>
Henry Adi Sumarto <henry.adisumarto@gmail.com>
Henry Bubert <google@mindeco.de>
Henry Chang <mr.changyuheng@gmail.com> Henry Chang <mr.changyuheng@gmail.com>
Herbert Georg Fischer <herbert.fischer@gmail.com> Herbert Georg Fischer <herbert.fischer@gmail.com>
Herbie Ong <herbie@google.com>
Heschi Kreinick <heschi@google.com> Heschi Kreinick <heschi@google.com>
Hilko Bengen <bengen@hilluzination.de>
Hiroaki Nakamura <hnakamur@gmail.com>
Hironao OTSUBO <motemen@gmail.com> Hironao OTSUBO <motemen@gmail.com>
Hiroshi Ioka <hirochachacha@gmail.com> Hiroshi Ioka <hirochachacha@gmail.com>
Hitoshi Mitake <mitake.hitoshi@gmail.com> Hitoshi Mitake <mitake.hitoshi@gmail.com>
@ -570,6 +625,7 @@ Hu Keping <hukeping@huawei.com>
Hugues Bruant <hugues.bruant@gmail.com> Hugues Bruant <hugues.bruant@gmail.com>
Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com> Hyang-Ah Hana Kim <hakim@google.com> <hyangah@gmail.com>
Ian Gudger <ian@loosescre.ws> Ian Gudger <ian@loosescre.ws>
Ian Kent <iankent85@gmail.com>
Ian Lance Taylor <iant@golang.org> Ian Lance Taylor <iant@golang.org>
Ibrahim AshShohail <ibra.sho@gmail.com> Ibrahim AshShohail <ibra.sho@gmail.com>
Icarus Sparry <golang@icarus.freeuk.com> Icarus Sparry <golang@icarus.freeuk.com>
@ -577,13 +633,17 @@ Iccha Sethi <icchasethi@gmail.com>
Idora Shinatose <idora.shinatose@gmail.com> Idora Shinatose <idora.shinatose@gmail.com>
Igor Bernstein <igorbernstein@google.com> Igor Bernstein <igorbernstein@google.com>
Igor Dolzhikov <bluesriverz@gmail.com> Igor Dolzhikov <bluesriverz@gmail.com>
Igor Vashyst <ivashyst@gmail.com>
Ilya Tocar <ilya.tocar@intel.com> Ilya Tocar <ilya.tocar@intel.com>
INADA Naoki <songofacandy@gmail.com> INADA Naoki <songofacandy@gmail.com>
Inanc Gumus <m@inanc.io>
Ingo Krabbe <ikrabbe.ask@gmail.com> Ingo Krabbe <ikrabbe.ask@gmail.com>
Ingo Oeser <nightlyone@googlemail.com> <nightlyone@gmail.com> Ingo Oeser <nightlyone@googlemail.com> <nightlyone@gmail.com>
Irieda Noboru <irieda@gmail.com> Irieda Noboru <irieda@gmail.com>
Isaac Wagner <ibw@isaacwagner.me> Isaac Wagner <ibw@isaacwagner.me>
Iskander Sharipov <iskander.sharipov@intel.com> <quasilyte@gmail.com>
Ivan Babrou <ivan@cloudflare.com> Ivan Babrou <ivan@cloudflare.com>
Ivan Bertona <ivan.bertona@gmail.com>
Ivan Krasin <krasin@golang.org> Ivan Krasin <krasin@golang.org>
Ivan Moscoso <moscoso@gmail.com> Ivan Moscoso <moscoso@gmail.com>
Ivan Ukhov <ivan.ukhov@gmail.com> Ivan Ukhov <ivan.ukhov@gmail.com>
@ -605,6 +665,7 @@ James David Chalfant <james.chalfant@gmail.com>
James Fysh <james.fysh@gmail.com> James Fysh <james.fysh@gmail.com>
James Gray <james@james4k.com> James Gray <james@james4k.com>
James Hartig <fastest963@gmail.com> James Hartig <fastest963@gmail.com>
James Lawrence <jljatone@gmail.com>
James Meneghello <rawrz0r@gmail.com> James Meneghello <rawrz0r@gmail.com>
James Myers <jfmyers9@gmail.com> James Myers <jfmyers9@gmail.com>
James Neve <jamesoneve@gmail.com> James Neve <jamesoneve@gmail.com>
@ -614,11 +675,13 @@ James Schofield <james@shoeboxapp.com>
James Smith <jrs1995@icloud.com> James Smith <jrs1995@icloud.com>
James Sweet <james.sweet88@googlemail.com> James Sweet <james.sweet88@googlemail.com>
James Toy <nil@opensesame.st> James Toy <nil@opensesame.st>
James Treanor <jtreanor3@gmail.com>
James Tucker <raggi@google.com> James Tucker <raggi@google.com>
James Whitehead <jnwhiteh@gmail.com> James Whitehead <jnwhiteh@gmail.com>
Jamie Beverly <jamie.r.beverly@gmail.com> Jamie Beverly <jamie.r.beverly@gmail.com>
Jamie Gennis <jgennis@google.com> <jgennis@gmail.com> Jamie Gennis <jgennis@google.com> <jgennis@gmail.com>
Jamie Kerr <jkerr113@googlemail.com> Jamie Kerr <jkerr113@googlemail.com>
Jamie Liu <jamieliu@google.com>
Jamie Stackhouse <contin673@gmail.com> Jamie Stackhouse <contin673@gmail.com>
Jamie Turner <jamwt@dropbox.com> Jamie Turner <jamwt@dropbox.com>
Jamie Wilkinson <jaq@spacepants.org> Jamie Wilkinson <jaq@spacepants.org>
@ -630,6 +693,7 @@ Jan Mercl <0xjnml@gmail.com> <befelemepeseveze@gmail.com>
Jan Newmarch <jan.newmarch@gmail.com> Jan Newmarch <jan.newmarch@gmail.com>
Jan Ziak <0xe2.0x9a.0x9b@gmail.com> Jan Ziak <0xe2.0x9a.0x9b@gmail.com>
Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com> Jani Monoses <jani.monoses@ubuntu.com> <jani.monoses@gmail.com>
Jared Culp <jculp14@gmail.com>
Jaroslavas Počepko <jp@webmaster.ms> Jaroslavas Počepko <jp@webmaster.ms>
Jason Barnett <jason.w.barnett@gmail.com> Jason Barnett <jason.w.barnett@gmail.com>
Jason Buberel <jbuberel@google.com> Jason Buberel <jbuberel@google.com>
@ -638,11 +702,15 @@ Jason Del Ponte <delpontej@gmail.com>
Jason Hall <jasonhall@google.com> Jason Hall <jasonhall@google.com>
Jason Smale <jsmale@zendesk.com> Jason Smale <jsmale@zendesk.com>
Jason Travis <infomaniac7@gmail.com> Jason Travis <infomaniac7@gmail.com>
Jason Wangsadinata <jwangsadinata@gmail.com>
Javier Segura <javism@gmail.com>
Jay Conrod <jayconrod@google.com> Jay Conrod <jayconrod@google.com>
Jay Weisskopf <jay@jayschwa.net> Jay Weisskopf <jay@jayschwa.net>
Jean-Francois Cantin <jfcantin@gmail.com>
Jean-Marc Eurin <jmeurin@google.com> Jean-Marc Eurin <jmeurin@google.com>
Jean-Nicolas Moal <jn.moal@gmail.com> Jean-Nicolas Moal <jn.moal@gmail.com>
Jed Denlea <jed@fastly.com> Jed Denlea <jed@fastly.com>
Jeet Parekh <jeetparekh96@gmail.com>
Jeff (Zhefu) Jiang <jeffjiang@google.com> Jeff (Zhefu) Jiang <jeffjiang@google.com>
Jeff Craig <jeffcraig@google.com> Jeff Craig <jeffcraig@google.com>
Jeff Hodges <jeff@somethingsimilar.com> Jeff Hodges <jeff@somethingsimilar.com>
@ -651,6 +719,7 @@ Jeff R. Allen <jra@nella.org> <jeff.allen@gmail.com>
Jeff Sickel <jas@corpus-callosum.com> Jeff Sickel <jas@corpus-callosum.com>
Jeff Wendling <jeff@spacemonkey.com> Jeff Wendling <jeff@spacemonkey.com>
Jeffrey H <jeffreyh192@gmail.com> Jeffrey H <jeffreyh192@gmail.com>
Jelte Fennema <github-tech@jeltef.nl>
Jens Frederich <jfrederich@gmail.com> Jens Frederich <jfrederich@gmail.com>
Jeremiah Harmsen <jeremiah@google.com> Jeremiah Harmsen <jeremiah@google.com>
Jeremy Jackins <jeremyjackins@gmail.com> Jeremy Jackins <jeremyjackins@gmail.com>
@ -664,12 +733,14 @@ Jihyun Yu <yjh0502@gmail.com>
Jim Cote <jfcote87@gmail.com> Jim Cote <jfcote87@gmail.com>
Jim Kingdon <jim@bolt.me> Jim Kingdon <jim@bolt.me>
Jim McGrath <jimmc2@gmail.com> Jim McGrath <jimmc2@gmail.com>
Jimmy Frasche <soapboxcicero@gmail.com>
Jimmy Zelinskie <jimmyzelinskie@gmail.com> Jimmy Zelinskie <jimmyzelinskie@gmail.com>
Jin-wook Jeong <jeweljar@hanmail.net> Jin-wook Jeong <jeweljar@hanmail.net>
Jingcheng Zhang <diogin@gmail.com> Jingcheng Zhang <diogin@gmail.com>
Jingguo Yao <yaojingguo@gmail.com> Jingguo Yao <yaojingguo@gmail.com>
Jiong Du <londevil@gmail.com> Jiong Du <londevil@gmail.com>
Jirka Daněk <dnk@mail.muni.cz> Jirka Daněk <dnk@mail.muni.cz>
Jiulong Wang <jiulongw@gmail.com>
Joakim Sernbrant <serbaut@gmail.com> Joakim Sernbrant <serbaut@gmail.com>
Joe Farrell <joe2farrell@gmail.com> Joe Farrell <joe2farrell@gmail.com>
Joe Harrison <joehazzers@gmail.com> Joe Harrison <joehazzers@gmail.com>
@ -734,10 +805,13 @@ Josh Holland <jrh@joshh.co.uk>
Josh Roppo <joshroppo@gmail.com> Josh Roppo <joshroppo@gmail.com>
Joshua Boelter <joshua.boelter@intel.com> Joshua Boelter <joshua.boelter@intel.com>
Joshua Chase <jcjoshuachase@gmail.com> Joshua Chase <jcjoshuachase@gmail.com>
Joshua Rubin <joshua@rubixconsulting.com>
Josselin Costanzi <josselin@costanzi.fr> Josselin Costanzi <josselin@costanzi.fr>
Jostein Stuhaug <js@solidsystem.no> Jostein Stuhaug <js@solidsystem.no>
JP Sugarbroad <jpsugar@google.com> JP Sugarbroad <jpsugar@google.com>
JT Olds <jtolds@xnet5.com> JT Olds <jtolds@xnet5.com>
Juan Carlos <juanjcsr@gmail.com>
Jude Pereira <judebpereira@gmail.com>
Jukka-Pekka Kekkonen <karatepekka@gmail.com> Jukka-Pekka Kekkonen <karatepekka@gmail.com>
Julia Hansbrough <flowerhack@google.com> Julia Hansbrough <flowerhack@google.com>
Julian Kornberger <jk+github@digineo.de> Julian Kornberger <jk+github@digineo.de>
@ -746,6 +820,7 @@ Julian Phillips <julian@quantumfyre.co.uk>
Julien Schmidt <google@julienschmidt.com> Julien Schmidt <google@julienschmidt.com>
Julio Montes <julio.montes@intel.com> Julio Montes <julio.montes@intel.com>
Jungho Ahn <jhahn@google.com> Jungho Ahn <jhahn@google.com>
Junya Hayashi <ledmonster@gmail.com>
Jure Ham <jure.ham@zemanta.com> Jure Ham <jure.ham@zemanta.com>
Justin Nuß <nuss.justin@gmail.com> Justin Nuß <nuss.justin@gmail.com>
Justyn Temme <justyntemme@gmail.com> Justyn Temme <justyntemme@gmail.com>
@ -758,7 +833,9 @@ Kamil Chmielewski <kamil.chm@gmail.com>
Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com> Kamil Kisiel <kamil@kamilkisiel.net> <kamil.kisiel@gmail.com>
Kang Hu <hukangustc@gmail.com> Kang Hu <hukangustc@gmail.com>
Karan Dhiman <karandhi@ca.ibm.com> Karan Dhiman <karandhi@ca.ibm.com>
Karel Pazdera <pazderak@gmail.com>
Karoly Negyesi <chx1975@gmail.com> Karoly Negyesi <chx1975@gmail.com>
Karsten Köhler <karsten.koehler95@gmail.com>
Kashav Madan <kshvmdn@gmail.com> Kashav Madan <kshvmdn@gmail.com>
Kate Manson <kate.manson@izettle.com> Kate Manson <kate.manson@izettle.com>
Kato Kazuyoshi <kato.kazuyoshi@gmail.com> Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
@ -779,6 +856,7 @@ Ken Rockot <ken@oz.gs> <ken.rockot@gmail.com>
Ken Sedgwick <ken@bonsai.com> Ken Sedgwick <ken@bonsai.com>
Ken Thompson <ken@golang.org> Ken Thompson <ken@golang.org>
Kenji Kaneda <kenji.kaneda@gmail.com> Kenji Kaneda <kenji.kaneda@gmail.com>
Kenji Yano <kenji.yano@gmail.com>
Kenneth Shaw <kenshaw@gmail.com> Kenneth Shaw <kenshaw@gmail.com>
Kenny Grant <kennygrant@gmail.com> Kenny Grant <kennygrant@gmail.com>
Kevin Ballard <kevin@sb.org> Kevin Ballard <kevin@sb.org>
@ -786,10 +864,13 @@ Kevin Burke <kev@inburke.com>
Kevin Kirsche <kev.kirsche@gmail.com> Kevin Kirsche <kev.kirsche@gmail.com>
Kevin Klues <klueska@gmail.com> <klueska@google.com> Kevin Klues <klueska@gmail.com> <klueska@google.com>
Kevin Malachowski <chowski@google.com> Kevin Malachowski <chowski@google.com>
Kevin Ruffin <kruffin@gmail.com>
Kevin Vu <kevin.m.vu@gmail.com> Kevin Vu <kevin.m.vu@gmail.com>
Kieran Colford <kieran@kcolford.com>
Kim Shrier <kshrier@racktopsystems.com> Kim Shrier <kshrier@racktopsystems.com>
Kim Yongbin <kybinz@gmail.com> Kim Yongbin <kybinz@gmail.com>
Kirill Smelkov <kirr@nexedi.com> Kirill Smelkov <kirr@nexedi.com>
Kirk Han <kirk91.han@gmail.com>
Kirklin McDonald <kirklin.mcdonald@gmail.com> Kirklin McDonald <kirklin.mcdonald@gmail.com>
Klaus Post <klauspost@gmail.com> Klaus Post <klauspost@gmail.com>
Kodie Goodwin <kodiegoodwin@gmail.com> Kodie Goodwin <kodiegoodwin@gmail.com>
@ -801,31 +882,40 @@ Kris Nova <kris@nivenly.com>
Kris Rousey <krousey@google.com> Kris Rousey <krousey@google.com>
Kristopher Watts <traetox@gmail.com> Kristopher Watts <traetox@gmail.com>
Kun Li <likunarmstrong@gmail.com> Kun Li <likunarmstrong@gmail.com>
Kunpei Sakai <namusyaka@gmail.com>
Kyle Consalus <consalus@gmail.com> Kyle Consalus <consalus@gmail.com>
Kyle Isom <kyle@gokyle.net> Kyle Isom <kyle@gokyle.net>
Kyle Jones <kyle@kyledj.com> Kyle Jones <kyle@kyledj.com>
Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com> Kyle Lemons <kyle@kylelemons.net> <kevlar@google.com>
Kyle Shannon <kyle@pobox.com>
Kyohei Kadota <lufia@lufia.org>
Kyrylo Silin <silin@kyrylo.org> Kyrylo Silin <silin@kyrylo.org>
L Campbell <unpantsu@gmail.com> L Campbell <unpantsu@gmail.com>
Lai Jiangshan <eag0628@gmail.com> Lai Jiangshan <eag0628@gmail.com>
Lakshay Garg <lakshay.garg.1996@gmail.com>
Lann Martin <lannm@google.com>
Larry Hosken <lahosken@golang.org> Larry Hosken <lahosken@golang.org>
Lars Jeppesen <jeppesen.lars@gmail.com> Lars Jeppesen <jeppesen.lars@gmail.com>
Lars Wiegman <lars@namsral.com> Lars Wiegman <lars@namsral.com>
Larz Conwell <larzconwell@gmail.com> Larz Conwell <larzconwell@gmail.com>
Laurent Voisin <lpvoisin@gmail.com>
Laurie Clark-Michalek <laurie@qubit.com> Laurie Clark-Michalek <laurie@qubit.com>
LE Manh Cuong <cuong.manhle.vn@gmail.com> LE Manh Cuong <cuong.manhle.vn@gmail.com>
Lee Hinman <hinman@gmail.com> Lee Hinman <hinman@gmail.com>
Lee Packham <lpackham@gmail.com> Lee Packham <lpackham@gmail.com>
Leigh McCulloch <leighmcc@gmail.com>
Leo Rudberg <ljr@google.com> Leo Rudberg <ljr@google.com>
Leon Klingele <git@leonklingele.de> Leon Klingele <git@leonklingele.de>
Lev Shamardin <shamardin@gmail.com> Lev Shamardin <shamardin@gmail.com>
Lewin Bormann <lewin.bormann@gmail.com> Lewin Bormann <lewin.bormann@gmail.com>
Lion Yang <lion@aosc.xyz> Lion Yang <lion@aosc.xyz>
Lloyd Dewolf <foolswisdom@gmail.com> Lloyd Dewolf <foolswisdom@gmail.com>
Lorenz Bauer <lmb@cloudflare.com>
Lorenzo Masini <rugginoso@develer.com> Lorenzo Masini <rugginoso@develer.com>
Lorenzo Stoakes <lstoakes@gmail.com> Lorenzo Stoakes <lstoakes@gmail.com>
Louis Kruger <louisk@google.com> Louis Kruger <louisk@google.com>
Luan Santos <cfcluan@gmail.com> Luan Santos <cfcluan@gmail.com>
Luca Bruno <luca.bruno@coreos.com>
Luca Greco <luca.greco@alcacoop.it> Luca Greco <luca.greco@alcacoop.it>
Lucas Bremgartner <lucas.bremgartner@gmail.com> Lucas Bremgartner <lucas.bremgartner@gmail.com>
Lucas Clemente <lclemente@google.com> Lucas Clemente <lclemente@google.com>
@ -837,15 +927,20 @@ Luit van Drongelen <luitvd@gmail.com>
Luka Zakrajšek <tr00.g33k@gmail.com> Luka Zakrajšek <tr00.g33k@gmail.com>
Lukasz Milewski <lmmilewski@gmail.com> Lukasz Milewski <lmmilewski@gmail.com>
Luke Curley <qpingu@gmail.com> Luke Curley <qpingu@gmail.com>
Luke Granger-Brown <git@lukegb.com>
Luna Duclos <luna.duclos@palmstonegames.com> Luna Duclos <luna.duclos@palmstonegames.com>
Luuk van Dijk <lvd@golang.org> <lvd@google.com> Luuk van Dijk <lvd@golang.org> <lvd@google.com>
Lyle Franklin <lylejfranklin@gmail.com>
Lynn Boger <laboger@linux.vnet.ibm.com> Lynn Boger <laboger@linux.vnet.ibm.com>
Ma Peiqi <mapeiqi2017@gmail.com> Ma Peiqi <mapeiqi2017@gmail.com>
Magnus Hiie <magnus.hiie@gmail.com> Magnus Hiie <magnus.hiie@gmail.com>
Maicon Costa <maiconscosta@gmail.com>
Maksym Trykur <maksym.trykur@gmail.com> Maksym Trykur <maksym.trykur@gmail.com>
Mal Curtis <mal@mal.co.nz> Mal Curtis <mal@mal.co.nz>
Manfred Touron <m@42.am> Manfred Touron <m@42.am>
Manish Goregaokar <manishsmail@gmail.com>
Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com> Manoj Dayaram <platform-dev@moovweb.com> <manoj.dayaram@moovweb.com>
Mansour Rahimi <rahimi.mnr@gmail.com>
Manu Garg <manugarg@google.com> Manu Garg <manugarg@google.com>
Manu S Ajith <neo@codingarena.in> Manu S Ajith <neo@codingarena.in>
Manuel Mendez <mmendez534@gmail.com> Manuel Mendez <mmendez534@gmail.com>
@ -861,9 +956,12 @@ Marius Nuennerich <mnu@google.com>
Mark Adams <mark@markadams.me> Mark Adams <mark@markadams.me>
Mark Bucciarelli <mkbucc@gmail.com> Mark Bucciarelli <mkbucc@gmail.com>
Mark Harrison <marhar@google.com> Mark Harrison <marhar@google.com>
Mark Percival <m@mdp.im>
Mark Pulford <mark@kyne.com.au>
Mark Ryan <mark.d.ryan@intel.com> Mark Ryan <mark.d.ryan@intel.com>
Mark Severson <miquella@gmail.com> Mark Severson <miquella@gmail.com>
Mark Theunissen <mark.theunissen@gmail.com> Mark Theunissen <mark.theunissen@gmail.com>
Mark Wolfe <mark@wolfe.id.au>
Mark Zavislak <zavislak@google.com> Mark Zavislak <zavislak@google.com>
Marko Juhani Silokunnas <marko.silokunnas@gmail.com> Marko Juhani Silokunnas <marko.silokunnas@gmail.com>
Marko Mikulicic <mkm@google.com> Marko Mikulicic <mkm@google.com>
@ -884,6 +982,7 @@ Martin Neubauer <m.ne@gmx.net>
Martin Olsen <github.com@martinolsen.net> Martin Olsen <github.com@martinolsen.net>
Martin Olsson <martin@minimum.se> Martin Olsson <martin@minimum.se>
Martin Probst <martin@probst.io> Martin Probst <martin@probst.io>
Martins Sipenko <martins.sipenko@gmail.com>
Martynas Budriūnas <mabu@google.com> Martynas Budriūnas <mabu@google.com>
Marvin Stenger <marvin.stenger94@gmail.com> Marvin Stenger <marvin.stenger94@gmail.com>
Marwan Sulaiman <marwan.sulaiman@work.co> Marwan Sulaiman <marwan.sulaiman@work.co>
@ -891,7 +990,10 @@ Maryan Hratson <gmarik@gmail.com>
Masahiro Furudate <masahiro.furudate@gmail.com> Masahiro Furudate <masahiro.furudate@gmail.com>
Masahiro Wakame <vvakame@gmail.com> Masahiro Wakame <vvakame@gmail.com>
Masaki Yoshida <yoshida.masaki@gmail.com> Masaki Yoshida <yoshida.masaki@gmail.com>
Mat Byczkowski <mbyczkowski@gmail.com>
Máté Gulyás <mgulyas86@gmail.com> Máté Gulyás <mgulyas86@gmail.com>
Matej Baćo <matejbaco@gmail.com>
Mateus Amin <mateus.amin@gmail.com>
Mateusz Czapliński <czapkofan@gmail.com> Mateusz Czapliński <czapkofan@gmail.com>
Mathias Beke <git@denbeke.be> Mathias Beke <git@denbeke.be>
Mathias Hall-Andersen <mathias@hall-andersen.dk> Mathias Hall-Andersen <mathias@hall-andersen.dk>
@ -902,6 +1004,7 @@ Matt Aimonetti <mattaimonetti@gmail.com>
Matt Blair <me@matthewblair.net> Matt Blair <me@matthewblair.net>
Matt Bostock <matt@mattbostock.com> Matt Bostock <matt@mattbostock.com>
Matt Brown <mdbrown@google.com> Matt Brown <mdbrown@google.com>
Matt Dee <mdee@hioscar.com>
Matt Drollette <matt@drollette.com> Matt Drollette <matt@drollette.com>
Matt Harden <matt.harden@gmail.com> Matt Harden <matt.harden@gmail.com>
Matt Jibson <matt.jibson@gmail.com> Matt Jibson <matt.jibson@gmail.com>
@ -914,6 +1017,7 @@ Matt Strong <mstrong1341@gmail.com>
Matt T. Proud <matt.proud@gmail.com> Matt T. Proud <matt.proud@gmail.com>
Matt Williams <gh@mattyw.net> <mattyjwilliams@gmail.com> Matt Williams <gh@mattyw.net> <mattyjwilliams@gmail.com>
Matthew Brennan <matty.brennan@gmail.com> Matthew Brennan <matty.brennan@gmail.com>
Matthew Broberg <matthewbbroberg@gmail.com>
Matthew Cottingham <mattcottingham@gmail.com> Matthew Cottingham <mattcottingham@gmail.com>
Matthew Dempsky <mdempsky@google.com> Matthew Dempsky <mdempsky@google.com>
Matthew Denton <mdenton@skyportsystems.com> Matthew Denton <mdenton@skyportsystems.com>
@ -921,17 +1025,21 @@ Matthew Holt <Matthew.Holt+git@gmail.com>
Matthew Horsnell <matthew.horsnell@gmail.com> Matthew Horsnell <matthew.horsnell@gmail.com>
Matthieu Hauglustaine <matt.hauglustaine@gmail.com> Matthieu Hauglustaine <matt.hauglustaine@gmail.com>
Matthieu Olivier <olivier.matthieu@gmail.com> Matthieu Olivier <olivier.matthieu@gmail.com>
Matthijs Kooijman <matthijs@stdin.nl>
Max Riveiro <kavu13@gmail.com> Max Riveiro <kavu13@gmail.com>
Max Schmitt <max@schmitt.mx>
Maxim Khitrov <max@mxcrypt.com> Maxim Khitrov <max@mxcrypt.com>
Maxim Pimenov <mpimenov@google.com> Maxim Pimenov <mpimenov@google.com>
Maxim Ushakov <ushakov@google.com> Maxim Ushakov <ushakov@google.com>
Maxime de Roucy <maxime.deroucy@gmail.com> Maxime de Roucy <maxime.deroucy@gmail.com>
Máximo Cuadros Ortiz <mcuadros@gmail.com> Máximo Cuadros Ortiz <mcuadros@gmail.com>
Maxwell Krohn <themax@gmail.com> Maxwell Krohn <themax@gmail.com>
Mayank Kumar <krmayankk@gmail.com>
Meir Fischer <meirfischer@gmail.com> Meir Fischer <meirfischer@gmail.com>
Meng Zhuo <mengzhuo1203@gmail.com> Meng Zhuo <mengzhuo1203@gmail.com>
Mhd Sulhan <m.shulhan@gmail.com> Mhd Sulhan <m.shulhan@gmail.com>
Micah Stetson <micah.stetson@gmail.com> Micah Stetson <micah.stetson@gmail.com>
Michael Brandenburg <mbrandenburg@bolste.com>
Michael Chaten <mchaten@gmail.com> Michael Chaten <mchaten@gmail.com>
Michael Darakananda <pongad@google.com> Michael Darakananda <pongad@google.com>
Michael Edwards <medwards@walledcity.ca> Michael Edwards <medwards@walledcity.ca>
@ -949,25 +1057,30 @@ Michael Marineau <michael.marineau@coreos.com>
Michael Matloob <matloob@google.com> Michael Matloob <matloob@google.com>
Michael McConville <momcconville@gmail.com> Michael McConville <momcconville@gmail.com>
Michael McGreevy <mcgreevy@golang.org> Michael McGreevy <mcgreevy@golang.org>
Michael McLoughlin <mmcloughlin@gmail.com>
Michael Munday <munday@ca.ibm.com> Michael Munday <munday@ca.ibm.com>
Michael Pearson <mipearson@gmail.com> Michael Pearson <mipearson@gmail.com>
Michael Piatek <piatek@google.com> Michael Piatek <piatek@google.com>
Michael Pratt <mpratt@google.com> Michael Pratt <mpratt@google.com>
Michael Schaller <michael@5challer.de> Michael Schaller <michael@5challer.de>
Michael Schurter <michael.schurter@gmail.com>
Michael Shields <mshields@google.com> Michael Shields <mshields@google.com>
Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com> Michael Stapelberg <michael@stapelberg.de> <mstplbrg@googlemail.com>
Michael Steinert <mike.steinert@gmail.com>
Michael T. Jones <mtj@google.com> <michael.jones@gmail.com> Michael T. Jones <mtj@google.com> <michael.jones@gmail.com>
Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com> Michael Teichgräber <mteichgraeber@gmx.de> <mt4swm@googlemail.com>
Michael Vetter <g.bluehut@gmail.com> Michael Vetter <g.bluehut@gmail.com>
Michal Bohuslávek <mbohuslavek@gmail.com> Michal Bohuslávek <mbohuslavek@gmail.com>
Michal Cierniak <cierniak@google.com> Michal Cierniak <cierniak@google.com>
Michał Derkacz <ziutek@lnet.pl> Michał Derkacz <ziutek@lnet.pl>
Michal Pristas <michal.pristas@gmail.com>
Michalis Kargakis <michaliskargakis@gmail.com> Michalis Kargakis <michaliskargakis@gmail.com>
Michel Lespinasse <walken@google.com> Michel Lespinasse <walken@google.com>
Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com> Miek Gieben <miek@miek.nl> <remigius.gieben@gmail.com>
Miguel Mendez <stxmendez@gmail.com> Miguel Mendez <stxmendez@gmail.com>
Miguel Molina <hi@mvader.me> Miguel Molina <hi@mvader.me>
Mihai Borobocea <MihaiBorobocea@gmail.com> Mihai Borobocea <MihaiBorobocea@gmail.com>
Mihail Minaev <minaev.mike@gmail.com>
Mikael Tillenius <mikti42@gmail.com> Mikael Tillenius <mikti42@gmail.com>
Mike Andrews <mra@xoba.com> Mike Andrews <mra@xoba.com>
Mike Appleby <mike@app.leby.org> Mike Appleby <mike@app.leby.org>
@ -995,9 +1108,11 @@ Morten Siebuhr <sbhr@sbhr.dk>
Môshe van der Sterre <moshevds@gmail.com> Môshe van der Sterre <moshevds@gmail.com>
Mostyn Bramley-Moore <mostyn@antipode.se> Mostyn Bramley-Moore <mostyn@antipode.se>
Mrunal Patel <mrunalp@gmail.com> Mrunal Patel <mrunalp@gmail.com>
Muhammad Falak R Wani <falakreyaz@gmail.com>
Muhammed Uluyol <uluyol0@gmail.com> Muhammed Uluyol <uluyol0@gmail.com>
Mura Li <mura_li@castech.com.tw> Mura Li <mura_li@castech.com.tw>
Nan Deng <monnand@gmail.com> Nan Deng <monnand@gmail.com>
Naoki Kanatani <k12naoki@gmail.com>
Nathan Caza <mastercactapus@gmail.com> Nathan Caza <mastercactapus@gmail.com>
Nathan Humphreys <nkhumphreys@gmail.com> Nathan Humphreys <nkhumphreys@gmail.com>
Nathan John Youngman <nj@nathany.com> Nathan John Youngman <nj@nathany.com>
@ -1027,6 +1142,7 @@ Nick Miyake <nmiyake@users.noreply.github.com>
Nick Patavalis <nick.patavalis@gmail.com> Nick Patavalis <nick.patavalis@gmail.com>
Nick Petroni <npetroni@cs.umd.edu> Nick Petroni <npetroni@cs.umd.edu>
Nick Robinson <nrobinson13@gmail.com> Nick Robinson <nrobinson13@gmail.com>
Nicolas BRULEZ <n.brulez@gmail.com>
Nicolas Kaiser <nikai@nikai.net> Nicolas Kaiser <nikai@nikai.net>
Nicolas Owens <mischief@offblast.org> Nicolas Owens <mischief@offblast.org>
Nicolas S. Dade <nic.dade@gmail.com> Nicolas S. Dade <nic.dade@gmail.com>
@ -1037,8 +1153,10 @@ Nik Nyby <nnyby@columbia.edu>
Niklas Schnelle <niklas.schnelle@gmail.com> Niklas Schnelle <niklas.schnelle@gmail.com>
Niko Dziemba <niko@dziemba.com> Niko Dziemba <niko@dziemba.com>
Nikolay Turpitko <nikolay@turpitko.com> Nikolay Turpitko <nikolay@turpitko.com>
Nils Larsgård <nilsmagnus@gmail.com>
Niranjan Godbole <niranjan8192@gmail.com> Niranjan Godbole <niranjan8192@gmail.com>
Noah Campbell <noahcampbell@gmail.com> Noah Campbell <noahcampbell@gmail.com>
Noble Johnson <noblepoly@gmail.com>
Nodir Turakulov <nodir@google.com> Nodir Turakulov <nodir@google.com>
Norberto Lopes <nlopes.ml@gmail.com> Norberto Lopes <nlopes.ml@gmail.com>
Odin Ugedal <odin@ugedal.com> Odin Ugedal <odin@ugedal.com>
@ -1073,6 +1191,7 @@ Patrick Riley <pfr@google.com>
Patrick Smith <pat42smith@gmail.com> Patrick Smith <pat42smith@gmail.com>
Paul A Querna <paul.querna@gmail.com> Paul A Querna <paul.querna@gmail.com>
Paul Borman <borman@google.com> Paul Borman <borman@google.com>
Paul Boyd <boyd.paul2@gmail.com>
Paul Chang <paulchang@google.com> Paul Chang <paulchang@google.com>
Paul Hammond <paul@paulhammond.org> Paul Hammond <paul@paulhammond.org>
Paul Hankin <paulhankin@google.com> Paul Hankin <paulhankin@google.com>
@ -1081,8 +1200,10 @@ Paul Lalonde <paul.a.lalonde@gmail.com>
Paul Marks <pmarks@google.com> Paul Marks <pmarks@google.com>
Paul Meyer <paul.meyer@microsoft.com> Paul Meyer <paul.meyer@microsoft.com>
Paul Nasrat <pnasrat@google.com> Paul Nasrat <pnasrat@google.com>
Paul PISCUC <paul.piscuc@gmail.com>
Paul Querna <pquerna@apache.org> Paul Querna <pquerna@apache.org>
Paul Rosania <paul.rosania@gmail.com> Paul Rosania <paul.rosania@gmail.com>
Paul Ruest <pruest@gmail.com>
Paul Sbarra <Sbarra.Paul@gmail.com> Paul Sbarra <Sbarra.Paul@gmail.com>
Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com> Paul Smith <paulsmith@pobox.com> <paulsmith@gmail.com>
Paul van Brouwershaven <paul@vanbrouwershaven.com> Paul van Brouwershaven <paul@vanbrouwershaven.com>
@ -1116,6 +1237,8 @@ Peter Waldschmidt <peter@waldschmidt.com>
Peter Waller <peter.waller@gmail.com> Peter Waller <peter.waller@gmail.com>
Peter Weinberger <pjw@golang.org> Peter Weinberger <pjw@golang.org>
Peter Williams <pwil3058@gmail.com> Peter Williams <pwil3058@gmail.com>
Peter Wu <pwu@cloudflare.com>
Petrica Voicu <pvoicu@paypal.com>
Phil Pennock <pdp@golang.org> Phil Pennock <pdp@golang.org>
Philip Børgesen <philip.borgesen@gmail.com> Philip Børgesen <philip.borgesen@gmail.com>
Philip Hofer <phofer@umich.edu> Philip Hofer <phofer@umich.edu>
@ -1125,6 +1248,7 @@ Pierre Roullon <pierre.roullon@gmail.com>
Piers <google@hellopiers.pro> Piers <google@hellopiers.pro>
Pieter Droogendijk <pieter@binky.org.uk> Pieter Droogendijk <pieter@binky.org.uk>
Pietro Gagliardi <pietro10@mac.com> Pietro Gagliardi <pietro10@mac.com>
Pontus Leitzler <leitzler@gmail.com>
Prasanna Swaminathan <prasanna@mediamath.com> Prasanna Swaminathan <prasanna@mediamath.com>
Prashant Varanasi <prashant@prashantv.com> Prashant Varanasi <prashant@prashantv.com>
Pravendra Singh <hackpravj@gmail.com> Pravendra Singh <hackpravj@gmail.com>
@ -1137,19 +1261,25 @@ Quentin Renard <contact@asticode.com>
Quentin Smith <quentin@golang.org> Quentin Smith <quentin@golang.org>
Quinn Slack <sqs@sourcegraph.com> Quinn Slack <sqs@sourcegraph.com>
Quoc-Viet Nguyen <afelion@gmail.com> Quoc-Viet Nguyen <afelion@gmail.com>
Radek Sohlich <sohlich@gmail.com>
Radu Berinde <radu@cockroachlabs.com> Radu Berinde <radu@cockroachlabs.com>
Rafal Jeczalik <rjeczalik@gmail.com> Rafal Jeczalik <rjeczalik@gmail.com>
Rahul Chaudhry <rahulchaudhry@chromium.org> Rahul Chaudhry <rahulchaudhry@chromium.org>
Raif S. Naffah <go@naffah-raif.name> Raif S. Naffah <go@naffah-raif.name>
Rajat Goel <rajat.goel2010@gmail.com> Rajat Goel <rajat.goel2010@gmail.com>
Rajath Agasthya <rajathagasthya@gmail.com>
Rajender Reddy Kompally <rajenderreddykompally@gmail.com>
Ralph Corderoy <ralph@inputplus.co.uk> Ralph Corderoy <ralph@inputplus.co.uk>
Ramazan AYYILDIZ <rayyildiz@gmail.com>
Ramesh Dharan <dharan@google.com> Ramesh Dharan <dharan@google.com>
Raph Levien <raph@google.com> Raph Levien <raph@google.com>
Raphael Geronimi <raphael.geronimi@gmail.com> Raphael Geronimi <raphael.geronimi@gmail.com>
Raul Silvera <rsilvera@google.com> Raul Silvera <rsilvera@google.com>
RaviTeja Pothana <ravi.tezu@gmail.com>
Ray Tung <rtung@thoughtworks.com> Ray Tung <rtung@thoughtworks.com>
Raymond Kazlauskas <raima220@gmail.com> Raymond Kazlauskas <raima220@gmail.com>
Rebecca Stambler <rstambler@golang.org> Rebecca Stambler <rstambler@golang.org>
Reilly Watson <reillywatson@gmail.com>
Reinaldo de Souza Jr <juniorz@gmail.com> Reinaldo de Souza Jr <juniorz@gmail.com>
Remi Gillig <remigillig@gmail.com> Remi Gillig <remigillig@gmail.com>
Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com> Rémy Oudompheng <oudomphe@phare.normalesup.org> <remyoudompheng@gmail.com>
@ -1187,10 +1317,13 @@ Rodrigo Rafael Monti Kochenburger <divoxx@gmail.com>
Roger Pau Monné <royger@gmail.com> Roger Pau Monné <royger@gmail.com>
Roger Peppe <rogpeppe@gmail.com> Roger Peppe <rogpeppe@gmail.com>
Roland Shoemaker <rolandshoemaker@gmail.com> Roland Shoemaker <rolandshoemaker@gmail.com>
Roman Budnikov <romanyx90@yandex.ru>
Ron Hashimoto <mail@h2so5.net> Ron Hashimoto <mail@h2so5.net>
Ron Minnich <rminnich@gmail.com> Ron Minnich <rminnich@gmail.com>
Ross Chater <rdchater@gmail.com>
Ross Light <light@google.com> <rlight2@gmail.com> Ross Light <light@google.com> <rlight2@gmail.com>
Rowan Worth <sqweek@gmail.com> Rowan Worth <sqweek@gmail.com>
Rudi Kramer <rudi.kramer@gmail.com>
Rui Ueyama <ruiu@google.com> Rui Ueyama <ruiu@google.com>
Russ Cox <rsc@golang.org> Russ Cox <rsc@golang.org>
Russell Haering <russellhaering@gmail.com> Russell Haering <russellhaering@gmail.com>
@ -1202,6 +1335,8 @@ Ryan Hitchman <hitchmanr@gmail.com>
Ryan Lower <rpjlower@gmail.com> Ryan Lower <rpjlower@gmail.com>
Ryan Seys <ryan@ryanseys.com> Ryan Seys <ryan@ryanseys.com>
Ryan Slade <ryanslade@gmail.com> Ryan Slade <ryanslade@gmail.com>
Ryoichi KATO <ryo1kato@gmail.com>
Ryuji Iwata <qt.luigi@gmail.com>
Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com> Ryuzo Yamamoto <ryuzo.yamamoto@gmail.com>
S.Çağlar Onur <caglar@10ur.org> S.Çağlar Onur <caglar@10ur.org>
Sai Cheemalapati <saicheems@google.com> Sai Cheemalapati <saicheems@google.com>
@ -1223,6 +1358,7 @@ Sasha Lionheart <lionhearts@google.com>
Sasha Sobol <sasha@scaledinference.com> Sasha Sobol <sasha@scaledinference.com>
Scott Barron <scott.barron@github.com> Scott Barron <scott.barron@github.com>
Scott Bell <scott@sctsm.com> Scott Bell <scott@sctsm.com>
Scott Crunkleton <crunk1@gmail.com>
Scott Ferguson <scottwferg@gmail.com> Scott Ferguson <scottwferg@gmail.com>
Scott Lawrence <bytbox@gmail.com> Scott Lawrence <bytbox@gmail.com>
Scott Mansfield <smansfield@netflix.com> Scott Mansfield <smansfield@netflix.com>
@ -1236,11 +1372,15 @@ Sean Harger <sharger@google.com>
Sean Rees <sean@erifax.org> Sean Rees <sean@erifax.org>
Sebastien Binet <seb.binet@gmail.com> Sebastien Binet <seb.binet@gmail.com>
Sébastien Paolacci <sebastien.paolacci@gmail.com> Sébastien Paolacci <sebastien.paolacci@gmail.com>
Seiji Takahashi <timaki.st@gmail.com>
Sergei Skorobogatov <skorobo@rambler.ru> Sergei Skorobogatov <skorobo@rambler.ru>
Sergey 'SnakE' Gromov <snake.scaly@gmail.com> Sergey 'SnakE' Gromov <snake.scaly@gmail.com>
Sergey Arseev <sergey.arseev@intel.com> Sergey Arseev <sergey.arseev@intel.com>
Sergey Frolov <sfrolov@google.com>
Sergey Mishin <sergeymishine@gmail.com> Sergey Mishin <sergeymishine@gmail.com>
Sergey Semin <gray12511@gmail.com>
Sergio Luis O. B. Correia <sergio@correia.cc> Sergio Luis O. B. Correia <sergio@correia.cc>
Sergiusz Bazanski <bazanski@gmail.com>
Seth Hoenig <seth.a.hoenig@gmail.com> Seth Hoenig <seth.a.hoenig@gmail.com>
Seth Vargo <sethvargo@gmail.com> Seth Vargo <sethvargo@gmail.com>
Shahar Kohanim <skohanim@gmail.com> Shahar Kohanim <skohanim@gmail.com>
@ -1270,6 +1410,7 @@ Srdjan Petrovic <spetrovic@google.com>
Sridhar Venkatakrishnan <sridhar@laddoo.net> Sridhar Venkatakrishnan <sridhar@laddoo.net>
StalkR <stalkr@stalkr.net> StalkR <stalkr@stalkr.net>
Stan Schwertly <stan@schwertly.com> Stan Schwertly <stan@schwertly.com>
Stanislav Afanasev <php.progger@gmail.com>
Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com> Stefan Nilsson <snilsson@nada.kth.se> <trolleriprofessorn@gmail.com>
Stéphane Travostino <stephane.travostino@gmail.com> Stéphane Travostino <stephane.travostino@gmail.com>
Stephen Ma <stephenm@golang.org> Stephen Ma <stephenm@golang.org>
@ -1277,6 +1418,7 @@ Stephen McQuay <stephen@mcquay.me>
Stephen Searles <stephens2424@gmail.com> Stephen Searles <stephens2424@gmail.com>
Stephen Weinberg <stephen@q5comm.com> Stephen Weinberg <stephen@q5comm.com>
Steve Francia <spf@golang.org> Steve Francia <spf@golang.org>
Steve Gilbert <stevegilbert23@gmail.com>
Steve McCoy <mccoyst@gmail.com> Steve McCoy <mccoyst@gmail.com>
Steve Newman <snewman@google.com> Steve Newman <snewman@google.com>
Steve Phillips <elimisteve@gmail.com> Steve Phillips <elimisteve@gmail.com>
@ -1288,13 +1430,16 @@ Steven Hartland <steven.hartland@multiplay.co.uk>
Steven Wilkin <stevenwilkin@gmail.com> Steven Wilkin <stevenwilkin@gmail.com>
Sugu Sougoumarane <ssougou@gmail.com> Sugu Sougoumarane <ssougou@gmail.com>
Suharsh Sivakumar <suharshs@google.com> Suharsh Sivakumar <suharshs@google.com>
Sukrit Handa <sukrit.handa@utoronto.ca>
Sunny <me@darkowlzz.space> Sunny <me@darkowlzz.space>
Suyash <dextrous93@gmail.com> Suyash <dextrous93@gmail.com>
Suzy Mueller <suzmue@golang.org> Suzy Mueller <suzmue@golang.org>
Sven Almgren <sven@tras.se> Sven Almgren <sven@tras.se>
Sven Blumenstein <svbl@google.com> Sven Blumenstein <svbl@google.com>
Sylvain Zimmer <sylvain@sylvainzimmer.com>
Syohei YOSHIDA <syohex@gmail.com> Syohei YOSHIDA <syohex@gmail.com>
Szabolcs Nagy <nsz@port70.net> Szabolcs Nagy <nsz@port70.net>
Tad Fisher <tadfisher@gmail.com>
Tad Glines <tad.glines@gmail.com> Tad Glines <tad.glines@gmail.com>
Taj Khattra <taj.khattra@gmail.com> Taj Khattra <taj.khattra@gmail.com>
Takashi Matsuo <tmatsuo@google.com> Takashi Matsuo <tmatsuo@google.com>
@ -1303,15 +1448,18 @@ Takuto Ikuta <tikuta@google.com>
Takuya Ueda <uedatakuya@gmail.com> Takuya Ueda <uedatakuya@gmail.com>
Tal Shprecher <tshprecher@gmail.com> Tal Shprecher <tshprecher@gmail.com>
Tamir Duberstein <tamird@gmail.com> Tamir Duberstein <tamird@gmail.com>
Tao Wang <twang2218@gmail.com>
Tarmigan Casebolt <tarmigan@gmail.com> Tarmigan Casebolt <tarmigan@gmail.com>
Taro Aoki <aizu.s1230022@gmail.com> Taro Aoki <aizu.s1230022@gmail.com>
Taru Karttunen <taruti@taruti.net> Taru Karttunen <taruti@taruti.net>
Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Ted Kornish <golang@tedkornish.com> Ted Kornish <golang@tedkornish.com>
Terin Stock <terinjokes@gmail.com>
Terrel Shumway <gopher@shumway.us> Terrel Shumway <gopher@shumway.us>
Tetsuo Kiso <tetsuokiso9@gmail.com> Tetsuo Kiso <tetsuokiso9@gmail.com>
Than McIntosh <thanm@google.com> Than McIntosh <thanm@google.com>
Thanatat Tamtan <acoshift@gmail.com> Thanatat Tamtan <acoshift@gmail.com>
Thiago Avelino <t@avelino.xxx>
Thiago Fransosi Farina <thiago.farina@gmail.com> <tfarina@chromium.org> Thiago Fransosi Farina <thiago.farina@gmail.com> <tfarina@chromium.org>
Thomas Alan Copeland <talan.copeland@gmail.com> Thomas Alan Copeland <talan.copeland@gmail.com>
Thomas Bonfort <thomas.bonfort@gmail.com> Thomas Bonfort <thomas.bonfort@gmail.com>
@ -1320,19 +1468,23 @@ Thomas de Zeeuw <thomasdezeeuw@gmail.com>
Thomas Desrosiers <thomasdesr@gmail.com> Thomas Desrosiers <thomasdesr@gmail.com>
Thomas Habets <habets@google.com> Thomas Habets <habets@google.com>
Thomas Kappler <tkappler@gmail.com> Thomas Kappler <tkappler@gmail.com>
Thomas Wanielista <tomwans@gmail.com>
Thorben Krueger <thorben.krueger@gmail.com> Thorben Krueger <thorben.krueger@gmail.com>
Thordur Bjornsson <thorduri@secnorth.net> Thordur Bjornsson <thorduri@secnorth.net>
Tilman Dilo <tilman.dilo@gmail.com> Tilman Dilo <tilman.dilo@gmail.com>
Tim Cooijmans <timcooijmans@gmail.com> Tim Cooijmans <timcooijmans@gmail.com>
Tim Cooper <tim.cooper@layeh.com>
Tim Ebringer <tim.ebringer@gmail.com> Tim Ebringer <tim.ebringer@gmail.com>
Tim Heckman <t@heckman.io> Tim Heckman <t@heckman.io>
Tim Henderson <tim.tadh@gmail.com> Tim Henderson <tim.tadh@gmail.com>
Tim Hockin <thockin@google.com> Tim Hockin <thockin@google.com>
Tim Swast <swast@google.com> Tim Swast <swast@google.com>
Tim Wright <tenortim@gmail.com>
Timo Savola <timo.savola@gmail.com> Timo Savola <timo.savola@gmail.com>
Timo Truyts <alkaloid.btx@gmail.com> Timo Truyts <alkaloid.btx@gmail.com>
Timothy Studd <tim@timstudd.com> Timothy Studd <tim@timstudd.com>
Tipp Moseley <tipp@google.com> Tipp Moseley <tipp@google.com>
Tobias Assarsson <tobias.assarsson@gmail.com>
Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com> Tobias Columbus <tobias.columbus@gmail.com> <tobias.columbus@googlemail.com>
Tobias Klauser <tklauser@distanz.ch> Tobias Klauser <tklauser@distanz.ch>
Toby Burress <kurin@google.com> Toby Burress <kurin@google.com>
@ -1340,6 +1492,8 @@ Todd Neal <todd@tneal.org>
Todd Wang <toddwang@gmail.com> Todd Wang <toddwang@gmail.com>
Tom Bergan <tombergan@google.com> Tom Bergan <tombergan@google.com>
Tom Heng <zhm20070928@gmail.com> Tom Heng <zhm20070928@gmail.com>
Tom Lanyon <tomlanyon@google.com>
Tom Levy <tomlevy93@gmail.com>
Tom Linford <tomlinford@gmail.com> Tom Linford <tomlinford@gmail.com>
Tom Szymanski <tgs@google.com> Tom Szymanski <tgs@google.com>
Tom Wilkie <tom@weave.works> Tom Wilkie <tom@weave.works>
@ -1358,9 +1512,12 @@ Trey Tacon <ttacon@gmail.com>
Tristan Amini <tamini01@ca.ibm.com> Tristan Amini <tamini01@ca.ibm.com>
Tristan Colgate <tcolgate@gmail.com> Tristan Colgate <tcolgate@gmail.com>
Tristan Ooohry <ooohry@gmail.com> Tristan Ooohry <ooohry@gmail.com>
Troels Thomsen <troels@thomsen.io>
Trung Nguyen <trung.n.k@gmail.com> Trung Nguyen <trung.n.k@gmail.com>
Tudor Golubenco <tudor.g@gmail.com> Tudor Golubenco <tudor.g@gmail.com>
Tugdual Saunier <tugdual.saunier@gmail.com>
Tuo Shan <sturbo89@gmail.com> <shantuo@google.com> Tuo Shan <sturbo89@gmail.com> <shantuo@google.com>
Tyler Bui-Palsulich <tpalsulich@google.com>
Tyler Bunnell <tylerbunnell@gmail.com> Tyler Bunnell <tylerbunnell@gmail.com>
Tyler Treat <ttreat31@gmail.com> Tyler Treat <ttreat31@gmail.com>
Tzu-Jung Lee <roylee17@currant.com> Tzu-Jung Lee <roylee17@currant.com>
@ -1393,10 +1550,13 @@ Wade Simmons <wade@wades.im>
Walter Poupore <wpoupore@google.com> Walter Poupore <wpoupore@google.com>
Wander Lairson Costa <wcosta@mozilla.com> Wander Lairson Costa <wcosta@mozilla.com>
Wedson Almeida Filho <wedsonaf@google.com> Wedson Almeida Filho <wedsonaf@google.com>
Wèi Cōngruì <crvv.mail@gmail.com>
Wei Guangjing <vcc.163@gmail.com> Wei Guangjing <vcc.163@gmail.com>
Wei Xiao <wei.xiao@arm.com> Wei Xiao <wei.xiao@arm.com>
Weichao Tang <tevic.tt@gmail.com> Weichao Tang <tevic.tt@gmail.com>
Wembley G. Leach, Jr <wembley.gl@gmail.com>
Will Chan <willchan@google.com> Will Chan <willchan@google.com>
Will Faught <will.faught@gmail.com>
Will Norris <willnorris@google.com> Will Norris <willnorris@google.com>
Will Storey <will@summercat.com> Will Storey <will@summercat.com>
Willem van der Schyff <willemvds@gmail.com> Willem van der Schyff <willemvds@gmail.com>
@ -1405,6 +1565,7 @@ William Josephson <wjosephson@gmail.com>
William Orr <will@worrbase.com> <ay1244@gmail.com> William Orr <will@worrbase.com> <ay1244@gmail.com>
Wisdom Omuya <deafgoat@gmail.com> Wisdom Omuya <deafgoat@gmail.com>
Wu Yunzhou <yunzhouwu@gmail.com> Wu Yunzhou <yunzhouwu@gmail.com>
Xi Ruoyao <xry23333@gmail.com>
Xia Bin <snyh@snyh.org> Xia Bin <snyh@snyh.org>
Xing Xing <mikespook@gmail.com> Xing Xing <mikespook@gmail.com>
Xu Fei <badgangkiller@gmail.com> Xu Fei <badgangkiller@gmail.com>
@ -1412,6 +1573,7 @@ Xudong Zhang <felixmelon@gmail.com>
Xuyang Kang <xuyangkang@gmail.com> Xuyang Kang <xuyangkang@gmail.com>
Yan Zou <yzou@google.com> Yan Zou <yzou@google.com>
Yann Kerhervé <yann.kerherve@gmail.com> Yann Kerhervé <yann.kerherve@gmail.com>
Yann Salaün <yannsalaun1@gmail.com>
Yao Zhang <lunaria21@gmail.com> Yao Zhang <lunaria21@gmail.com>
Yasha Bubnov <girokompass@gmail.com> Yasha Bubnov <girokompass@gmail.com>
Yasuharu Goto <matope.ono@gmail.com> Yasuharu Goto <matope.ono@gmail.com>
@ -1423,23 +1585,30 @@ Yo-An Lin <yoanlin93@gmail.com>
Yongjian Xu <i3dmaster@gmail.com> Yongjian Xu <i3dmaster@gmail.com>
Yorman Arias <cixtords@gmail.com> Yorman Arias <cixtords@gmail.com>
Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp> Yoshiyuki Kanno <nekotaroh@gmail.com> <yoshiyuki.kanno@stoic.co.jp>
Yosuke Akatsuka <yosuke.akatsuka@gmail.com>
Yu Heng Zhang <annita.zhang@cn.ibm.com> Yu Heng Zhang <annita.zhang@cn.ibm.com>
Yu Xuan Zhang <zyxsh@cn.ibm.com> Yu Xuan Zhang <zyxsh@cn.ibm.com>
Yuki Yugui Sonoda <yugui@google.com> Yuki Yugui Sonoda <yugui@google.com>
Yukihiro Nishinaka <6elpinal@gmail.com>
Yusuke Kagiwada <block.rxckin.beats@gmail.com> Yusuke Kagiwada <block.rxckin.beats@gmail.com>
Yuusei Kuwana <kuwana@kumama.org> Yuusei Kuwana <kuwana@kumama.org>
Yuval Pavel Zholkover <paulzhol@gmail.com> Yuval Pavel Zholkover <paulzhol@gmail.com>
Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com> Yves Junqueira <yvesj@google.com> <yves.junqueira@gmail.com>
Zac Bergquist <zbergquist99@gmail.com> Zac Bergquist <zbergquist99@gmail.com>
Zach Bintliff <zbintliff@gmail.com> Zach Bintliff <zbintliff@gmail.com>
Zach Gershman <zachgersh@gmail.com>
Zak <zrjknill@gmail.com> Zak <zrjknill@gmail.com>
Zakatell Kanda <hi@zkanda.io> Zakatell Kanda <hi@zkanda.io>
Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com> Zellyn Hunter <zellyn@squareup.com> <zellyn@gmail.com>
Zev Goldstein <zev.goldstein@gmail.com> Zev Goldstein <zev.goldstein@gmail.com>
Zhengyu He <hzy@google.com>
Zhongtao Chen <chenzhongtao@126.com>
Zhongwei Yao <zhongwei.yao@arm.com> Zhongwei Yao <zhongwei.yao@arm.com>
Ziad Hatahet <hatahet@gmail.com> Ziad Hatahet <hatahet@gmail.com>
Zorion Arrizabalaga <zorionk@gmail.com> Zorion Arrizabalaga <zorionk@gmail.com>
Максим Федосеев <max.faceless.frei@gmail.com> Максим Федосеев <max.faceless.frei@gmail.com>
Роман Хавроненко <hagen1778@gmail.com>
Тарас Буник <tbunyk@gmail.com>
Фахриддин Балтаев <faxriddinjon@gmail.com> Фахриддин Балтаев <faxriddinjon@gmail.com>
张嵩 <zs349596@gmail.com> 张嵩 <zs349596@gmail.com>
申习之 <bronze1man@gmail.com> 申习之 <bronze1man@gmail.com>

View file

@ -31,15 +31,14 @@ in your web browser for source installation instructions.
### Contributing ### Contributing
Go is the work of hundreds of contributors. We appreciate your help! Go is the work of thousands of contributors. We appreciate your help!
To contribute, please read the contribution guidelines: To contribute, please read the contribution guidelines:
https://golang.org/doc/contribute.html https://golang.org/doc/contribute.html
Note that the Go project does not use GitHub pull requests, and that Note that the Go project uses the issue tracker for bug reports and
we use the issue tracker for bug reports and proposals only. See proposals only. See https://golang.org/wiki/Questions for a list of
https://golang.org/wiki/Questions for a list of places to ask places to ask questions about the Go language.
questions about the Go language.
[rf]: https://reneefrench.blogspot.com/ [rf]: https://reneefrench.blogspot.com/
[cc3-by]: https://creativecommons.org/licenses/by/3.0/ [cc3-by]: https://creativecommons.org/licenses/by/3.0/

View file

@ -11,4 +11,3 @@ compatibility.
next.txt is the only file intended to be mutated. It's a list of next.txt is the only file intended to be mutated. It's a list of
features that may be added to the next version. It only affects features that may be added to the next version. It only affects
warning output from the go api tool. warning output from the go api tool.

View file

@ -2,6 +2,7 @@ pkg encoding/json, method (*RawMessage) MarshalJSON() ([]uint8, error)
pkg math/big, const MaxBase = 36 pkg math/big, const MaxBase = 36
pkg math/big, type Word uintptr pkg math/big, type Word uintptr
pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error) pkg net, func ListenUnixgram(string, *UnixAddr) (*UDPConn, error)
pkg os, const ModeType = 2399141888
pkg os (linux-arm), const O_SYNC = 4096 pkg os (linux-arm), const O_SYNC = 4096
pkg os (linux-arm-cgo), const O_SYNC = 4096 pkg os (linux-arm-cgo), const O_SYNC = 4096
pkg syscall (darwin-386), const ImplementsGetwd = false pkg syscall (darwin-386), const ImplementsGetwd = false
@ -15,25 +16,30 @@ pkg syscall (darwin-amd64-cgo), func Fchflags(string, int) error
pkg syscall (freebsd-386), const AF_MAX = 38 pkg syscall (freebsd-386), const AF_MAX = 38
pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242 pkg syscall (freebsd-386), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386), const ELAST = 94 pkg syscall (freebsd-386), const ELAST = 94
pkg syscall (freebsd-386), const ImplementsGetwd = false
pkg syscall (freebsd-386), const O_CLOEXEC = 0 pkg syscall (freebsd-386), const O_CLOEXEC = 0
pkg syscall (freebsd-386), func Fchflags(string, int) error pkg syscall (freebsd-386), func Fchflags(string, int) error
pkg syscall (freebsd-386-cgo), const AF_MAX = 38 pkg syscall (freebsd-386-cgo), const AF_MAX = 38
pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242 pkg syscall (freebsd-386-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-386-cgo), const ELAST = 94 pkg syscall (freebsd-386-cgo), const ELAST = 94
pkg syscall (freebsd-386-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0 pkg syscall (freebsd-386-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), const AF_MAX = 38 pkg syscall (freebsd-amd64), const AF_MAX = 38
pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242 pkg syscall (freebsd-amd64), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64), const ELAST = 94 pkg syscall (freebsd-amd64), const ELAST = 94
pkg syscall (freebsd-amd64), const ImplementsGetwd = false
pkg syscall (freebsd-amd64), const O_CLOEXEC = 0 pkg syscall (freebsd-amd64), const O_CLOEXEC = 0
pkg syscall (freebsd-amd64), func Fchflags(string, int) error pkg syscall (freebsd-amd64), func Fchflags(string, int) error
pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38 pkg syscall (freebsd-amd64-cgo), const AF_MAX = 38
pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242 pkg syscall (freebsd-amd64-cgo), const DLT_MATCHING_MAX = 242
pkg syscall (freebsd-amd64-cgo), const ELAST = 94 pkg syscall (freebsd-amd64-cgo), const ELAST = 94
pkg syscall (freebsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0 pkg syscall (freebsd-amd64-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-arm), const AF_MAX = 38 pkg syscall (freebsd-arm), const AF_MAX = 38
pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262 pkg syscall (freebsd-arm), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085 pkg syscall (freebsd-arm), const BIOCSRTIMEOUT = 2148287085
pkg syscall (freebsd-arm), const ELAST = 94 pkg syscall (freebsd-arm), const ELAST = 94
pkg syscall (freebsd-arm), const ImplementsGetwd = false
pkg syscall (freebsd-arm), const O_CLOEXEC = 0 pkg syscall (freebsd-arm), const O_CLOEXEC = 0
pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019 pkg syscall (freebsd-arm), const SIOCAIFADDR = 2151967019
pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931 pkg syscall (freebsd-arm), const SIOCGIFSTATUS = 3274991931
@ -65,6 +71,7 @@ pkg syscall (freebsd-arm-cgo), const AF_MAX = 38
pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262 pkg syscall (freebsd-arm-cgo), const BIOCGRTIMEOUT = 1074545262
pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085 pkg syscall (freebsd-arm-cgo), const BIOCSRTIMEOUT = 2148287085
pkg syscall (freebsd-arm-cgo), const ELAST = 94 pkg syscall (freebsd-arm-cgo), const ELAST = 94
pkg syscall (freebsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0 pkg syscall (freebsd-arm-cgo), const O_CLOEXEC = 0
pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019 pkg syscall (freebsd-arm-cgo), const SIOCAIFADDR = 2151967019
pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931 pkg syscall (freebsd-arm-cgo), const SIOCGIFSTATUS = 3274991931
@ -98,6 +105,12 @@ pkg syscall (linux-amd64), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-amd64-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8 pkg syscall (linux-amd64-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-arm), type Cmsghdr struct, X__cmsg_data [0]uint8 pkg syscall (linux-arm), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (linux-arm-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8 pkg syscall (linux-arm-cgo), type Cmsghdr struct, X__cmsg_data [0]uint8
pkg syscall (netbsd-386), const ImplementsGetwd = false
pkg syscall (netbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-amd64), const ImplementsGetwd = false
pkg syscall (netbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const ImplementsGetwd = false
pkg syscall (netbsd-arm-cgo), const ImplementsGetwd = false
pkg syscall (netbsd-arm), const SizeofIfData = 132 pkg syscall (netbsd-arm), const SizeofIfData = 132
pkg syscall (netbsd-arm), func Fchflags(string, int) error pkg syscall (netbsd-arm), func Fchflags(string, int) error
pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8 pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
@ -106,6 +119,7 @@ pkg syscall (netbsd-arm-cgo), func Fchflags(string, int) error
pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8 pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
pkg syscall (openbsd-386), const BIOCGRTIMEOUT = 1074283118 pkg syscall (openbsd-386), const BIOCGRTIMEOUT = 1074283118
pkg syscall (openbsd-386), const BIOCSRTIMEOUT = 2148024941 pkg syscall (openbsd-386), const BIOCSRTIMEOUT = 2148024941
pkg syscall (openbsd-386), const ImplementsGetwd = false
pkg syscall (openbsd-386), const RTF_FMASK = 63496 pkg syscall (openbsd-386), const RTF_FMASK = 63496
pkg syscall (openbsd-386), const RTM_VERSION = 4 pkg syscall (openbsd-386), const RTM_VERSION = 4
pkg syscall (openbsd-386), const SIOCBRDGDADDR = 2150132039 pkg syscall (openbsd-386), const SIOCBRDGDADDR = 2150132039
@ -158,6 +172,7 @@ pkg syscall (openbsd-386), type Timespec struct, Sec int32
pkg syscall (openbsd-386), type Timeval struct, Sec int32 pkg syscall (openbsd-386), type Timeval struct, Sec int32
pkg syscall (openbsd-386-cgo), const BIOCGRTIMEOUT = 1074283118 pkg syscall (openbsd-386-cgo), const BIOCGRTIMEOUT = 1074283118
pkg syscall (openbsd-386-cgo), const BIOCSRTIMEOUT = 2148024941 pkg syscall (openbsd-386-cgo), const BIOCSRTIMEOUT = 2148024941
pkg syscall (openbsd-386-cgo), const ImplementsGetwd = false
pkg syscall (openbsd-386-cgo), const RTF_FMASK = 63496 pkg syscall (openbsd-386-cgo), const RTF_FMASK = 63496
pkg syscall (openbsd-386-cgo), const RTM_VERSION = 4 pkg syscall (openbsd-386-cgo), const RTM_VERSION = 4
pkg syscall (openbsd-386-cgo), const SIOCBRDGDADDR = 2150132039 pkg syscall (openbsd-386-cgo), const SIOCBRDGDADDR = 2150132039
@ -220,6 +235,7 @@ pkg syscall (openbsd-amd64), const EFER_NXE = 2048
pkg syscall (openbsd-amd64), const EFER_NXE ideal-int pkg syscall (openbsd-amd64), const EFER_NXE ideal-int
pkg syscall (openbsd-amd64), const EFER_SCE = 1 pkg syscall (openbsd-amd64), const EFER_SCE = 1
pkg syscall (openbsd-amd64), const EFER_SCE ideal-int pkg syscall (openbsd-amd64), const EFER_SCE ideal-int
pkg syscall (openbsd-amd64), const ImplementsGetwd = false
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH = 21 pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH = 21
pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH ideal-int pkg syscall (openbsd-amd64), const PMC5_PIPELINE_FLUSH ideal-int
pkg syscall (openbsd-amd64), const RTF_FMASK = 63496 pkg syscall (openbsd-amd64), const RTF_FMASK = 63496
@ -282,6 +298,7 @@ pkg syscall (openbsd-amd64-cgo), const EFER_NXE = 2048
pkg syscall (openbsd-amd64-cgo), const EFER_NXE ideal-int pkg syscall (openbsd-amd64-cgo), const EFER_NXE ideal-int
pkg syscall (openbsd-amd64-cgo), const EFER_SCE = 1 pkg syscall (openbsd-amd64-cgo), const EFER_SCE = 1
pkg syscall (openbsd-amd64-cgo), const EFER_SCE ideal-int pkg syscall (openbsd-amd64-cgo), const EFER_SCE ideal-int
pkg syscall (openbsd-amd64-cgo), const ImplementsGetwd = false
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH = 21 pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH = 21
pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH ideal-int pkg syscall (openbsd-amd64-cgo), const PMC5_PIPELINE_FLUSH ideal-int
pkg syscall (openbsd-amd64-cgo), const RTF_FMASK = 63496 pkg syscall (openbsd-amd64-cgo), const RTF_FMASK = 63496
@ -345,3 +362,24 @@ pkg syscall (openbsd-386-cgo), const SYS_KILL = 37
pkg syscall (openbsd-amd64), const SYS_KILL = 37 pkg syscall (openbsd-amd64), const SYS_KILL = 37
pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37 pkg syscall (openbsd-amd64-cgo), const SYS_KILL = 37
pkg unicode, const Version = "9.0.0" pkg unicode, const Version = "9.0.0"
pkg text/template/parse, method (*VariableNode) Copy() Node
pkg text/template/parse, method (*VariableNode) String() string
pkg text/template/parse, method (VariableNode) Position() Pos
pkg text/template/parse, method (VariableNode) Type() NodeType
pkg text/template/parse, type PipeNode struct, Decl []*VariableNode
pkg text/template/parse, type VariableNode struct
pkg text/template/parse, type VariableNode struct, Ident []string
pkg text/template/parse, type VariableNode struct, embedded NodeType
pkg text/template/parse, type VariableNode struct, embedded Pos
pkg syscall (windows-386), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-386), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-386), type CertContext struct, CertInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-386), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-386), type CertSimpleChain struct, TrustListInfo uintptr
pkg syscall (windows-amd64), type CertChainPolicyPara struct, ExtraPolicyPara uintptr
pkg syscall (windows-amd64), type CertChainPolicyStatus struct, ExtraPolicyStatus uintptr
pkg syscall (windows-amd64), type CertContext struct, CertInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, CrlInfo uintptr
pkg syscall (windows-amd64), type CertRevocationInfo struct, OidSpecificInfo uintptr
pkg syscall (windows-amd64), type CertSimpleChain struct, TrustListInfo uintptr

View file

@ -573,6 +573,7 @@ pkg encoding/xml, type TokenReader interface, Token() (Token, error)
pkg flag, method (*FlagSet) ErrorHandling() ErrorHandling pkg flag, method (*FlagSet) ErrorHandling() ErrorHandling
pkg flag, method (*FlagSet) Name() string pkg flag, method (*FlagSet) Name() string
pkg flag, method (*FlagSet) Output() io.Writer pkg flag, method (*FlagSet) Output() io.Writer
pkg html/template, type Srcset string
pkg math, func Erfcinv(float64) float64 pkg math, func Erfcinv(float64) float64
pkg math, func Erfinv(float64) float64 pkg math, func Erfinv(float64) float64
pkg math, func Round(float64) float64 pkg math, func Round(float64) float64
@ -594,7 +595,6 @@ pkg os, method (*SyscallError) Timeout() bool
pkg os, var ErrNoDeadline error pkg os, var ErrNoDeadline error
pkg strings, method (*Builder) Grow(int) pkg strings, method (*Builder) Grow(int)
pkg strings, method (*Builder) Len() int pkg strings, method (*Builder) Len() int
pkg strings, method (*Builder) ReadFrom(io.Reader) (int64, error)
pkg strings, method (*Builder) Reset() pkg strings, method (*Builder) Reset()
pkg strings, method (*Builder) String() string pkg strings, method (*Builder) String() string
pkg strings, method (*Builder) Write([]uint8) (int, error) pkg strings, method (*Builder) Write([]uint8) (int, error)
@ -618,24 +618,6 @@ pkg syscall (windows-386), func CreateProcessAsUser(Token, *uint16, *uint16, *Se
pkg syscall (windows-386), type SysProcAttr struct, Token Token pkg syscall (windows-386), type SysProcAttr struct, Token Token
pkg syscall (windows-amd64), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error pkg syscall (windows-amd64), func CreateProcessAsUser(Token, *uint16, *uint16, *SecurityAttributes, *SecurityAttributes, bool, uint32, *uint16, *uint16, *StartupInfo, *ProcessInformation) error
pkg syscall (windows-amd64), type SysProcAttr struct, Token Token pkg syscall (windows-amd64), type SysProcAttr struct, Token Token
pkg text/template/parse, const NodeBreak = 20
pkg text/template/parse, const NodeBreak NodeType
pkg text/template/parse, const NodeContinue = 21
pkg text/template/parse, const NodeContinue NodeType
pkg text/template/parse, method (*BreakNode) Copy() Node
pkg text/template/parse, method (*BreakNode) Position() Pos
pkg text/template/parse, method (*BreakNode) String() string
pkg text/template/parse, method (*BreakNode) Type() NodeType
pkg text/template/parse, method (*ContinueNode) Copy() Node
pkg text/template/parse, method (*ContinueNode) Position() Pos
pkg text/template/parse, method (*ContinueNode) String() string
pkg text/template/parse, method (*ContinueNode) Type() NodeType
pkg text/template/parse, type BreakNode struct
pkg text/template/parse, type BreakNode struct, embedded NodeType
pkg text/template/parse, type BreakNode struct, embedded Pos
pkg text/template/parse, type ContinueNode struct
pkg text/template/parse, type ContinueNode struct, embedded NodeType
pkg text/template/parse, type ContinueNode struct, embedded Pos
pkg time, func LoadLocationFromTZData(string, []uint8) (*Location, error) pkg time, func LoadLocationFromTZData(string, []uint8) (*Location, error)
pkg unicode, const Version = "10.0.0" pkg unicode, const Version = "10.0.0"
pkg unicode, var Masaram_Gondi *RangeTable pkg unicode, var Masaram_Gondi *RangeTable

View file

@ -134,7 +134,7 @@ be able to adapt to changing build environments and conditions. For
example, if we allowed extra configuration such as compiler flags or example, if we allowed extra configuration such as compiler flags or
command line recipes, then that configuration would need to be updated command line recipes, then that configuration would need to be updated
each time the build tools changed; it would also be inherently tied each time the build tools changed; it would also be inherently tied
to the use of a specific tool chain.</p> to the use of a specific toolchain.</p>
<h2>Getting started with the go command</h2> <h2>Getting started with the go command</h2>

View file

@ -268,6 +268,12 @@ view a wiki page. It will handle URLs prefixed with "/view/".
{{code "doc/articles/wiki/part2.go" `/^func viewHandler/` `/^}/`}} {{code "doc/articles/wiki/part2.go" `/^func viewHandler/` `/^}/`}}
<p>
Again, note the use of <code>_</code> to ignore the <code>error</code>
return value from <code>loadPage</code>. This is done here for simplicity
and generally considered bad practice. We will attend to this later.
</p>
<p> <p>
First, this function extracts the page title from <code>r.URL.Path</code>, First, this function extracts the page title from <code>r.URL.Path</code>,
the path component of the request URL. the path component of the request URL.
@ -282,12 +288,6 @@ The function then loads the page data, formats the page with a string of simple
HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>. HTML, and writes it to <code>w</code>, the <code>http.ResponseWriter</code>.
</p> </p>
<p>
Again, note the use of <code>_</code> to ignore the <code>error</code>
return value from <code>loadPage</code>. This is done here for simplicity
and generally considered bad practice. We will attend to this later.
</p>
<p> <p>
To use this handler, we rewrite our <code>main</code> function to To use this handler, we rewrite our <code>main</code> function to
initialize <code>http</code> using the <code>viewHandler</code> to handle initialize <code>http</code> using the <code>viewHandler</code> to handle

View file

@ -29,7 +29,7 @@ Instead, the compiler operates on a kind of semi-abstract instruction set,
and instruction selection occurs partly after code generation. and instruction selection occurs partly after code generation.
The assembler works on the semi-abstract form, so The assembler works on the semi-abstract form, so
when you see an instruction like <code>MOV</code> when you see an instruction like <code>MOV</code>
what the tool chain actually generates for that operation might what the toolchain actually generates for that operation might
not be a move instruction at all, perhaps a clear or load. not be a move instruction at all, perhaps a clear or load.
Or it might correspond exactly to the machine instruction with that name. Or it might correspond exactly to the machine instruction with that name.
In general, machine-specific operations tend to appear as themselves, while more general concepts like In general, machine-specific operations tend to appear as themselves, while more general concepts like
@ -139,7 +139,7 @@ The exact set depends on the architecture.
<p> <p>
There are four predeclared symbols that refer to pseudo-registers. There are four predeclared symbols that refer to pseudo-registers.
These are not real registers, but rather virtual registers maintained by These are not real registers, but rather virtual registers maintained by
the tool chain, such as a frame pointer. the toolchain, such as a frame pointer.
The set of pseudo-registers is the same for all architectures: The set of pseudo-registers is the same for all architectures:
</p> </p>
@ -738,6 +738,13 @@ The other codes are <code>-&gt;</code> (arithmetic right shift),
The ARM64 port is in an experimental state. The ARM64 port is in an experimental state.
</p> </p>
<p>
<code>R18</code> is the "platform register", reserved on the Apple platform.
<code>R27</code> and <code>R28</code> are reserved by the compiler and linker.
<code>R29</code> is the frame pointer.
<code>R30</code> is the link register.
</p>
<p> <p>
Instruction modifiers are appended to the instruction following a period. Instruction modifiers are appended to the instruction following a period.
The only modifiers are <code>P</code> (postincrement) and <code>W</code> The only modifiers are <code>P</code> (postincrement) and <code>W</code>
@ -752,11 +759,61 @@ Addressing modes:
<ul> <ul>
<li> <li>
<code>(R5, R6)</code>: Register pair for <code>LDP</code>/<code>STP</code>. <code>R0-&gt;16</code>
<br>
<code>R0&gt;&gt;16</code>
<br>
<code>R0&lt;&lt;16</code>
<br>
<code>R0@&gt;16</code>:
These are the same as on the 32-bit ARM.
</li>
<li>
<code>$(8&lt;&lt;12)</code>:
Left shift the immediate value <code>8</code> by <code>12</code> bits.
</li>
<li>
<code>8(R0)</code>:
Add the value of <code>R0</code> and <code>8</code>.
</li>
<li>
<code>(R2)(R0)</code>:
The location at <code>R0</code> plus <code>R2</code>.
</li>
<li>
<code>R0.UXTB</code>
<br>
<code>R0.UXTB&lt;&lt;imm</code>:
<code>UXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and zero-extend it to the size of <code>R0</code>.
<code>R0.UXTB&lt;&lt;imm</code>: left shift the result of <code>R0.UXTB</code> by <code>imm</code> bits.
The <code>imm</code> value can be 0, 1, 2, 3, or 4.
The other extensions include <code>UXTH</code> (16-bit), <code>UXTW</code> (32-bit), and <code>UXTX</code> (64-bit).
</li>
<li>
<code>R0.SXTB</code>
<br>
<code>R0.SXTB&lt;&lt;imm</code>:
<code>SXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and sign-extend it to the size of <code>R0</code>.
<code>R0.SXTB&lt;&lt;imm</code>: left shift the result of <code>R0.SXTB</code> by <code>imm</code> bits.
The <code>imm</code> value can be 0, 1, 2, 3, or 4.
The other extensions include <code>SXTH</code> (16-bit), <code>SXTW</code> (32-bit), and <code>SXTX</code> (64-bit).
</li>
<li>
<code>(R5, R6)</code>: Register pair for <code>LDAXP</code>/<code>LDP</code>/<code>LDXP</code>/<code>STLXP</code>/<code>STP</code>/<code>STP</code>.
</li> </li>
</ul> </ul>
<p>
Reference: <a href="/pkg/cmd/internal/obj/arm64">Go ARM64 Assembly Instructions Reference Manual</a>
</p>
<h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3> <h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
<p> <p>
@ -882,6 +939,12 @@ The value of <code>GOMIPS</code> environment variable (<code>hardfloat</code> or
<code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>. <code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
</p> </p>
<p>
The value of <code>GOMIPS64</code> environment variable (<code>hardfloat</code> or
<code>softfloat</code>) is made available to assembly code by predefining either
<code>GOMIPS64_hardfloat</code> or <code>GOMIPS64_softfloat</code>.
</p>
<h3 id="unsupported_opcodes">Unsupported opcodes</h3> <h3 id="unsupported_opcodes">Unsupported opcodes</h3>
<p> <p>

View file

@ -183,7 +183,6 @@ satisfaction of all parties. They are:
<li>Aditya Mukerjee &lt;dev@chimeracoder.net&gt; <li>Aditya Mukerjee &lt;dev@chimeracoder.net&gt;
<li>Andrew Gerrand &lt;adg@golang.org&gt; <li>Andrew Gerrand &lt;adg@golang.org&gt;
<li>Peggy Li &lt;peggyli.224@gmail.com&gt; <li>Peggy Li &lt;peggyli.224@gmail.com&gt;
<li>Sarah Adams &lt;sadams.codes@gmail.com&gt;
<li>Steve Francia &lt;steve.francia@gmail.com&gt; <li>Steve Francia &lt;steve.francia@gmail.com&gt;
<li>Verónica López &lt;gveronicalg@gmail.com&gt; <li>Verónica López &lt;gveronicalg@gmail.com&gt;
</ul> </ul>

View file

@ -118,6 +118,6 @@ guidelines</a> for information on design, testing, and our code review process.
<p> <p>
Check <a href="//golang.org/issue">the tracker</a> for Check <a href="//golang.org/issue">the tracker</a> for
open issues that interest you. Those labeled open issues that interest you. Those labeled
<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Ahelpwanted">helpwanted</a> <a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22">help wanted</a>
are particularly in need of outside help. are particularly in need of outside help.
</p> </p>

File diff suppressed because it is too large Load diff

View file

@ -3,28 +3,54 @@
"Path": "/doc/gdb" "Path": "/doc/gdb"
}--> }-->
<p><i> <!--
This applies to the standard toolchain (the <code>gc</code> Go NOTE: In this document and others in this directory, the convention is to
compiler and tools). Gccgo has native gdb support. set fixed-width phrases with non-fixed-width spaces, as in
Besides this overview you might want to consult the <code>hello</code> <code>world</code>.
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>. Do not send CLs removing the interior tags from such phrases.
</i></p> -->
<i>
<p>
The following instructions apply to the standard toolchain
(the <code>gc</code> Go compiler and tools).
Gccgo has native gdb support.
</p>
<p>
Note that
<a href="https://github.com/derekparker/delve">Delve</a> is a better
alternative to GDB when debugging Go programs built with the standard
toolchain. It understands the Go runtime, data structures, and
expressions better than GDB. Delve currently supports Linux, OSX,
and Windows on <code>amd64</code>.
For the most up-to-date list of supported platforms, please see
<a href="https://github.com/derekparker/delve/tree/master/Documentation/installation">
the Delve documentation</a>.
</p>
</i>
<p> <p>
GDB does not understand Go programs well. GDB does not understand Go programs well.
The stack management, threading, and runtime contain aspects that differ The stack management, threading, and runtime contain aspects that differ
enough from the execution model GDB expects that they can confuse enough from the execution model GDB expects that they can confuse
the debugger, even when the program is compiled with gccgo. the debugger and cause incorrect results even when the program is
As a consequence, although GDB can be useful in some situations, it is compiled with gccgo.
not a reliable debugger for Go programs, particularly heavily concurrent ones. As a consequence, although GDB can be useful in some situations (e.g.,
Moreover, it is not a priority for the Go project to address these issues, which debugging Cgo code, or debugging the runtime itself), it is not
are difficult. a reliable debugger for Go programs, particularly heavily concurrent
In short, the instructions below should be taken only as a guide to how ones. Moreover, it is not a priority for the Go project to address
to use GDB when it works, not as a guarantee of success. these issues, which are difficult.
</p>
<p>
In short, the instructions below should be taken only as a guide to how
to use GDB when it works, not as a guarantee of success.
Besides this overview you might want to consult the
<a href="http://sourceware.org/gdb/current/onlinedocs/gdb/">GDB manual</a>.
</p> </p>
<p> <p>
In time, a more Go-centric debugging architecture may be required.
</p> </p>
<h2 id="Introduction">Introduction</h2> <h2 id="Introduction">Introduction</h2>
@ -38,16 +64,15 @@ use to inspect a live process or a core dump.
<p> <p>
Pass the <code>'-w'</code> flag to the linker to omit the debug information Pass the <code>'-w'</code> flag to the linker to omit the debug information
(for example, <code>go build -ldflags "-w" prog.go</code>). (for example, <code>go</code> <code>build</code> <code>-ldflags=-w</code> <code>prog.go</code>).
</p> </p>
<p> <p>
The code generated by the <code>gc</code> compiler includes inlining of The code generated by the <code>gc</code> compiler includes inlining of
function invocations and registerization of variables. These optimizations function invocations and registerization of variables. These optimizations
can sometimes make debugging with <code>gdb</code> harder. To disable them can sometimes make debugging with <code>gdb</code> harder.
when debugging, pass the flags <code>-gcflags "-N -l"</code> to the If you find that you need to disable these optimizations,
<a href="/cmd/go"><code>go</code></a> command used to build the code being build your program using <code>go</code> <code>build</code> <code>-gcflags=all="-N -l"</code>.
debugged.
</p> </p>
<p> <p>
@ -94,7 +119,7 @@ Show the name, type and location of global variables:
<p> <p>
A recent extension mechanism to GDB allows it to load extension scripts for a A recent extension mechanism to GDB allows it to load extension scripts for a
given binary. The tool chain uses this to extend GDB with a handful of given binary. The toolchain uses this to extend GDB with a handful of
commands to inspect internals of the runtime code (such as goroutines) and to commands to inspect internals of the runtime code (such as goroutines) and to
pretty print the built-in map, slice and channel types. pretty print the built-in map, slice and channel types.
</p> </p>
@ -139,7 +164,7 @@ the DWARF code.
<p> <p>
If you're interested in what the debugging information looks like, run If you're interested in what the debugging information looks like, run
'<code>objdump -W a.out</code>' and browse through the <code>.debug_*</code> <code>objdump</code> <code>-W</code> <code>a.out</code> and browse through the <code>.debug_*</code>
sections. sections.
</p> </p>
@ -162,7 +187,7 @@ the form <code>pkg.(*MyType).Meth</code>.
<p> <p>
In this tutorial we will inspect the binary of the In this tutorial we will inspect the binary of the
<a href="/pkg/regexp/">regexp</a> package's unit tests. To build the binary, <a href="/pkg/regexp/">regexp</a> package's unit tests. To build the binary,
change to <code>$GOROOT/src/regexp</code> and run <code>go test -c</code>. change to <code>$GOROOT/src/regexp</code> and run <code>go</code> <code>test</code> <code>-c</code>.
This should produce an executable file named <code>regexp.test</code>. This should produce an executable file named <code>regexp.test</code>.
</p> </p>
@ -188,7 +213,7 @@ Loading Go Runtime support.
</pre> </pre>
<p> <p>
The message <code>"Loading Go Runtime support"</code> means that GDB loaded the The message "Loading Go Runtime support" means that GDB loaded the
extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>. extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>.
</p> </p>
@ -353,7 +378,7 @@ Stack level 0, frame at 0x7ffff7f9ff88:
</pre> </pre>
<p> <p>
The command <code>info locals</code> lists all variables local to the function and their values, but is a bit The command <code>info</code> <code>locals</code> lists all variables local to the function and their values, but is a bit
dangerous to use, since it will also try to print uninitialized variables. Uninitialized slices may cause gdb to try dangerous to use, since it will also try to print uninitialized variables. Uninitialized slices may cause gdb to try
to print arbitrary large arrays. to print arbitrary large arrays.
</p> </p>
@ -386,7 +411,7 @@ $3 = struct hchan&lt;*testing.T&gt;
</pre> </pre>
<p> <p>
That <code>struct hchan&lt;*testing.T&gt;</code> is the That <code>struct</code> <code>hchan&lt;*testing.T&gt;</code> is the
runtime-internal representation of a channel. It is currently empty, runtime-internal representation of a channel. It is currently empty,
or gdb would have pretty-printed its contents. or gdb would have pretty-printed its contents.
</p> </p>

View file

@ -16,11 +16,36 @@ git checkout <i>release-branch</i>
<p> <p>
Each major Go release is supported until there are two newer major releases. Each major Go release is supported until there are two newer major releases.
For example, Go 1.8 is supported until Go 1.10 is released, For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was
and Go 1.9 is supported until Go 1.11 is released. supported until the Go 1.8 release.
We fix critical problems, including <a href="/security">critical security problems</a>, We fix critical problems, including <a href="/security">critical security problems</a>,
in supported releases as needed by issuing minor revisions in supported releases as needed by issuing minor revisions
(for example, Go 1.9.1, Go 1.9.2, and so on). (for example, Go 1.6.1, Go 1.6.2, and so on).
</p>
<h2 id="go1.10">go1.10 (released 2018/02/16)</h2>
<p>
Go 1.10 is a major release of Go.
Read the <a href="/doc/go1.10">Go 1.10 Release Notes</a> for more information.
</p>
<h3 id="go1.10.minor">Minor revisions</h3>
<p>
go1.10.1 (released 2018/03/28) includes fixes to the compiler, runtime, and the
<code>archive/zip</code>, <code>crypto/tls</code>, <code>crypto/x509</code>,
<code>encoding/json</code>, <code>net</code>, <code>net/http</code>, and
<code>net/http/pprof</code> packages.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.1">Go
1.10.1 milestone</a> on our issue tracker for details.
</p>
<p>
go1.10.2 (released 2018/05/01) includes fixes to the compiler, linker, and go
command.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.10.2">Go
1.10.2 milestone</a> on our issue tracker for details.
</p> </p>
<h2 id="go1.9">go1.9 (released 2017/08/24)</h2> <h2 id="go1.9">go1.9 (released 2017/08/24)</h2>
@ -49,6 +74,34 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.2">Go
1.9.2 milestone</a> on our issue tracker for details. 1.9.2 milestone</a> on our issue tracker for details.
</p> </p>
<p>
go1.9.3 (released 2018/01/22) includes fixes to the compiler, runtime,
and the <code>database/sql</code>, <code>math/big</code>, <code>net/http</code>,
and <code>net/url</code> packages.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.3">Go
1.9.3 milestone</a> on our issue tracker for details.
</p>
<p>
go1.9.4 (released 2018/02/07) includes a security fix to “go get”.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.4">Go
1.9.4</a> milestone on our issue tracker for details.
</p>
<p>
go1.9.5 (released 2018/03/28) includes fixes to the compiler, go command, and
<code>net/http/pprof</code> package.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.5">Go
1.9.5 milestone</a> on our issue tracker for details.
</p>
<p>
go1.9.6 (released 2018/05/01) includes fixes to the compiler and go command.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.9.6">Go
1.9.6 milestone</a> on our issue tracker for details.
</p>
<h2 id="go1.8">go1.8 (released 2017/02/16)</h2> <h2 id="go1.8">go1.8 (released 2017/02/16)</h2>
<p> <p>
@ -99,6 +152,20 @@ See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.5">Go
1.8.5 milestone</a> on our issue tracker for details. 1.8.5 milestone</a> on our issue tracker for details.
</p> </p>
<p>
go1.8.6 (released 2018/01/22) includes the same fix in <code>math/big</code>
as Go 1.9.3 and was released at the same time.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.6">Go
1.8.6 milestone</a> on our issue tracker for details.
</p>
<p>
go1.8.7 (released 2018/02/07) includes a security fix to “go get”.
It contains the same fix as Go 1.9.4 and was released at the same time.
See the <a href="https://github.com/golang/go/issues?q=milestone%3AGo1.8.7">Go
1.8.7</a> milestone on our issue tracker for details.
</p>
<h2 id="go1.7">go1.7 (released 2016/08/15)</h2> <h2 id="go1.7">go1.7 (released 2016/08/15)</h2>
<p> <p>

View file

@ -3,6 +3,13 @@
"Template": true "Template": true
}--> }-->
<!--
NOTE: In this document and others in this directory, the convention is to
set fixed-width phrases with non-fixed-width spaces, as in
<code>hello</code> <code>world</code>.
Do not send CLs removing the interior tags from such phrases.
-->
<h2 id="introduction">Introduction</h2> <h2 id="introduction">Introduction</h2>
<p> <p>
@ -45,7 +52,7 @@ of code. The Go runtime provides <a href="https://golang.org/pkg/runtime/pprof/"
profiling data</a> in the format expected by the profiling data</a> in the format expected by the
<a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>. <a href="https://github.com/google/pprof/blob/master/doc/pprof.md">pprof visualization tool</a>.
The profiling data can be collected during testing The profiling data can be collected during testing
via <code>go test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/"> via <code>go</code> <code>test</code> or endpoints made available from the <a href="/pkg/net/http/pprof/">
net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter net/http/pprof</a> package. Users need to collect the profiling data and use pprof tools to filter
and visualize the top code paths. and visualize the top code paths.
</p> </p>
@ -119,7 +126,7 @@ so it is recommended to collect only a single profile at a time.
<p> <p>
The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a> The Go tools provide text, graph, and <a href="http://valgrind.org/docs/manual/cl-manual.html">callgrind</a>
visualization of the profile data via visualization of the profile data using
<code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>. <code><a href="https://github.com/google/pprof/blob/master/doc/pprof.md">go tool pprof</a></code>.
Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a> Read <a href="https://blog.golang.org/profiling-go-programs">Profiling Go programs</a>
to see them in action. to see them in action.
@ -149,9 +156,11 @@ in the listing.</p>
</p> </p>
<p> <p>
Another way to visualize profile data is a <a href="https://github.com/uber/go-torch">flame graph</a>. Another way to visualize profile data is a <a href="http://www.brendangregg.com/flamegraphs.html">flame graph</a>.
Flame graphs allow you to move in a specific ancestry path, so you can zoom Flame graphs allow you to move in a specific ancestry path, so you can zoom
in/out specific sections of code more easily. in/out of specific sections of code.
The <a href="https://github.com/google/pprof">upstream pprof</a>
has support for flame graphs.
</p> </p>
<p> <p>
@ -183,9 +192,19 @@ handler on :7777 at /custom_debug_path/profile:
<p> <p>
<pre> <pre>
mux := http.NewServeMux() package main
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
http.ListenAndServe(":7777", mux) import (
"log"
"net/http"
"net/http/pprof"
)
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/custom_debug_path/profile", pprof.Profile)
log.Fatal(http.ListenAndServe(":7777", mux))
}
</pre> </pre>
</p> </p>
@ -203,7 +222,7 @@ an execution tracer to trace the runtime events within an interval.
<p>Tracing enables us to:</p> <p>Tracing enables us to:</p>
<ul> <ul>
<li>Instrument and profile application latency in a Go process.</li> <li>Instrument and analyze application latency in a Go process.</li>
<li>Measure the cost of specific calls in a long chain of calls.</li> <li>Measure the cost of specific calls in a long chain of calls.</li>
<li>Figure out the utilization and performance improvements. <li>Figure out the utilization and performance improvements.
Bottlenecks are not always obvious without tracing data.</li> Bottlenecks are not always obvious without tracing data.</li>
@ -252,7 +271,8 @@ trace spans. You need to manually instrument your code to create, end, and annot
<p><strong>How should I propagate trace headers in Go libraries?</strong></p> <p><strong>How should I propagate trace headers in Go libraries?</strong></p>
<p> <p>
You can propagate trace identifiers and tags in the <code>context.Context</code>. You can propagate trace identifiers and tags in the
<a href="/pkg/context#Context"><code>context.Context</code></a>.
There is no canonical trace key or common representation of trace headers There is no canonical trace key or common representation of trace headers
in the industry yet. Each tracing provider is responsible for providing propagation in the industry yet. Each tracing provider is responsible for providing propagation
utilities in their Go libraries. utilities in their Go libraries.
@ -265,7 +285,8 @@ runtime can be included in a trace?</strong>
<p> <p>
The standard library and runtime are trying to expose several additional APIs The standard library and runtime are trying to expose several additional APIs
to notify on low level internal events. For example, httptrace.ClientTrace to notify on low level internal events. For example,
<a href="/pkg/net/http/httptrace#ClientTrace"><code>httptrace.ClientTrace</code></a>
provides APIs to follow low-level events in the life cycle of an outgoing request. provides APIs to follow low-level events in the life cycle of an outgoing request.
There is an ongoing effort to retrieve low-level runtime events from There is an ongoing effort to retrieve low-level runtime events from
the runtime execution tracer and allow users to define and record their user events. the runtime execution tracer and allow users to define and record their user events.
@ -303,25 +324,25 @@ create confusion.
<p><strong>How well do debuggers work with Go programs?</strong></p> <p><strong>How well do debuggers work with Go programs?</strong></p>
<p> <p>
As of Go 1.9, the DWARF info generated by the gc compiler is not complete The <code>gc</code> compiler performs optimizations such as
and sometimes makes debugging harder. There is an ongoing effort to improve the function inlining and variable registerization. These optimizations
DWARF information to help the debuggers display more accurate information. sometimes make debugging with debuggers harder. There is an ongoing
Until those improvements are in you may prefer to disable compiler effort to improve the quality of the DWARF information generated for
optimizations during development for more accuracy. To disable optimizations, optimized binaries. Until those improvements are available, we recommend
use the "-N -l" compiler flags. For example, the following command builds disabling optimizations when building the code being debugged. The following
a package with no compiler optimizations: command builds a package with no compiler optimizations:
<p> <p>
<pre> <pre>
$ go build -gcflags="-N -l" $ go build -gcflags=all="-N -l"
</pre> </pre>
</p> </p>
<p> As part of the improvement effort, Go 1.10 introduced a new compiler
As of Go 1.10, the Go binaries will have the required DWARF information flag <code>-dwarflocationlists</code>. The flag causes the compiler to
for accurate debugging. To enable the DWARF improvements, use the following add location lists that helps debuggers work with optimized binaries.
compiler flags and use GDB until Delve supports location lists: The following command builds a package with optimizations but with
</p> the DWARF location lists:
<p> <p>
<pre> <pre>
@ -333,9 +354,7 @@ $ go build -gcflags="-dwarflocationlists=true"
<p> <p>
Even though both delve and gdb provides CLIs, most editor integrations Even though both delve and gdb provides CLIs, most editor integrations
and IDEs provides debugging-specific user interfaces. Please refer to and IDEs provides debugging-specific user interfaces.
the <a href="/doc/editors.html">editors guide</a> to see the options
with debugger UI support.
</p> </p>
<p><strong>Is it possible to do postmortem debugging with Go programs?</strong></p> <p><strong>Is it possible to do postmortem debugging with Go programs?</strong></p>
@ -421,7 +440,7 @@ Use profiling tools instead first to address them.</p>
fine, and then it became serialized. It suggests that there might fine, and then it became serialized. It suggests that there might
be lock contention for a shared resource that creates a bottleneck.</p> be lock contention for a shared resource that creates a bottleneck.</p>
<p>See <a href="https://golang.org/cmd/trace/"><code>go tool trace</code></a> <p>See <a href="https://golang.org/cmd/trace/"><code>go</code> <code>tool</code> <code>trace</code></a>
to collect and analyze runtime traces. to collect and analyze runtime traces.
</p> </p>

View file

@ -33,199 +33,3 @@ community-maintained list of
<a href="https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins">IDEs and text editor plugins</a> <a href="https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins">IDEs and text editor plugins</a>
is available at the Wiki. is available at the Wiki.
</p> </p>
<p>
Each development environment integrates a number of Go-specific tools.
The following feature matrix lists and compares the most significant features.
</p>
<table class="features-matrix">
<tr>
<th></th>
<th><img title="Vim Go" src="/doc/editors/vimgo.png"><br>vim</th>
<th><img title="Visual Studio Code" src="/doc/editors/vscodego.png"><br>Visual Studio Code</th>
<th><img title="GoLand" src="/doc/editors/goland.png"><br>GoLand</th>
<th><img title="Go-Plus" src="/doc/editors/go-plus.png"><br>Atom</th>
</tr>
<tr>
<td class="feature-row" colspan="5">Editing features</td>
</tr>
<tr>
<td>Build and run from the editor/IDE</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Autocompletion of identifiers (variable, method, and function names)</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Type-aware autocompletion</td>
<td class="no">No</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<td>Rename identifiers</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Auto format, build, vet, and lint on save</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>1</sup></td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Auto insert import paths and remove unused on save</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>2</sup></td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Auto generate JSON, XML tags for struct fields</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td class="feature-row" colspan="5">Navigation features</td>
</tr>
<tr>
<td>Display documentation inline, or open godoc in browser</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Switch between <code>*.go</code> and <code>*_test.go</code> file</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">No</td>
</tr>
<tr>
<td>Jump to definition and referees</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Look up for interface implementations</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td>Search for callers and callees</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr>
<td class="feature-row" colspan="5">Testing and debugging features</td>
</tr>
<tr>
<td>Debugger support</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>3</sup></td>
</tr>
<tr>
<td>Run a single test case, all tests from file, or all tests from a package</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<td>Auto generate tests for packages, files and identifiers</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="no">No</td>
</tr>
<tr>
<td>Debug tests</td>
<td class="no">No</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes<sup>3</sup></td>
</tr>
<tr>
<td>Display test coverage</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
<td class="yes">Yes</td>
</tr>
<tr class="download">
<td></td>
<td><a href="https://github.com/fatih/vim-go">Install</a></td>
<td><a href="https://marketplace.visualstudio.com/items?itemName=lukehoban.Go">Install</a></td>
<td><a href="https://www.jetbrains.com/go">Install</a></td>
<td><a href="https://atom.io/packages/go-plus">Install</a></td>
</tr>
</table>
<p>
<sup>1</sup>Possible when enabled via Settings &gt; Go &gt; On Save, <code>go</code> <code>vet</code> and <code>golint</code> are available via plugins. Also runs tests on save if configured.
<br>
<sup>2</sup>Additionally, user input can disambiguate when two or more options are available.
<br>
<sup>3</sup>Available if the <a href="https://atom.io/packages/go-debug">go-debug</a> package is installed.
</p>
</div>
<style>
.features-matrix {
min-width: 800px;
border-collapse: collapse;
}
.features-matrix th {
width: 60px;
text-align: center;
font-size: 14px;
color: #666;
}
.features-matrix th img {
width: 48px;
}
.features-matrix .yes {
text-align: center;
}
.features-matrix .no {
text-align: center;
background-color: #ffe9e9;
}
.features-matrix .download {
font-weight: bold;
text-align: center;
}
.features-matrix td {
padding: 11px 5px 11px 5px;
border-bottom: solid 1px #ebebeb;
}
.features-matrix .feature-row {
background-color: #ebebeb;
font-weight: bold;
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -3588,8 +3588,7 @@ That's left as an exercise for the reader.
<p> <p>
Let's finish with a complete Go program, a web server. Let's finish with a complete Go program, a web server.
This one is actually a kind of web re-server. This one is actually a kind of web re-server.
Google provides a service at Google provides a service at <code>chart.apis.google.com</code>
<a href="http://chart.apis.google.com">http://chart.apis.google.com</a>
that does automatic formatting of data into charts and graphs. that does automatic formatting of data into charts and graphs.
It's hard to use interactively, though, It's hard to use interactively, though,
because you need to put the data into the URL as a query. because you need to put the data into the URL as a query.

View file

@ -166,7 +166,7 @@ providing a complete Go 1.1 implementation.
<h3 id="gc_flag">Command-line flag parsing</h3> <h3 id="gc_flag">Command-line flag parsing</h3>
<p> <p>
In the gc tool chain, the compilers and linkers now use the In the gc toolchain, the compilers and linkers now use the
same command-line flag parsing rules as the Go flag package, a departure same command-line flag parsing rules as the Go flag package, a departure
from the traditional Unix flag parsing. This may affect scripts that invoke from the traditional Unix flag parsing. This may affect scripts that invoke
the tool directly. the tool directly.
@ -305,7 +305,7 @@ The race detector is documented in <a href="/doc/articles/race_detector.html">a
<p> <p>
Due to the change of the <a href="#int"><code>int</code></a> to 64 bits and Due to the change of the <a href="#int"><code>int</code></a> to 64 bits and
a new internal <a href="//golang.org/s/go11func">representation of functions</a>, a new internal <a href="//golang.org/s/go11func">representation of functions</a>,
the arrangement of function arguments on the stack has changed in the gc tool chain. the arrangement of function arguments on the stack has changed in the gc toolchain.
Functions written in assembly will need to be revised at least Functions written in assembly will need to be revised at least
to adjust frame pointer offsets. to adjust frame pointer offsets.
</p> </p>
@ -395,7 +395,7 @@ Run <code>go help test</code> for more information.
The <a href="/cmd/fix/"><code>fix</code></a> command, usually run as The <a href="/cmd/fix/"><code>fix</code></a> command, usually run as
<code>go fix</code>, no longer applies fixes to update code from <code>go fix</code>, no longer applies fixes to update code from
before Go 1 to use Go 1 APIs. before Go 1 to use Go 1 APIs.
To update pre-Go 1 code to Go 1.1, use a Go 1.0 tool chain To update pre-Go 1 code to Go 1.1, use a Go 1.0 toolchain
to convert the code to Go 1.0 first. to convert the code to Go 1.0 first.
</p> </p>
@ -427,7 +427,7 @@ To build a file only with Go 1.0.x, use the converse constraint:
<h3 id="platforms">Additional platforms</h3> <h3 id="platforms">Additional platforms</h3>
<p> <p>
The Go 1.1 tool chain adds experimental support for <code>freebsd/arm</code>, The Go 1.1 toolchain adds experimental support for <code>freebsd/arm</code>,
<code>netbsd/386</code>, <code>netbsd/amd64</code>, <code>netbsd/arm</code>, <code>netbsd/386</code>, <code>netbsd/amd64</code>, <code>netbsd/arm</code>,
<code>openbsd/386</code> and <code>openbsd/amd64</code> platforms. <code>openbsd/386</code> and <code>openbsd/amd64</code> platforms.
</p> </p>

View file

@ -15,34 +15,37 @@ Do not send CLs removing the interior tags from such phrases.
ul li { margin: 0.5em 0; } ul li { margin: 0.5em 0; }
</style> </style>
<h2 id="introduction">DRAFT RELEASE NOTES - Introduction to Go 1.10</h2> <h2 id="introduction">Introduction to Go 1.10</h2>
<p><strong>
Go 1.10 is not yet released. These are work-in-progress
release notes. Go 1.10 is expected to be released in February 2018.
</strong></p>
<p> <p>
The latest Go release, version 1.10, arrives six months after <a href="go1.9">go1.9</a>. The latest Go release, version 1.10, arrives six months after <a href="go1.9">Go 1.9</a>.
Most of its changes are in the implementation of the toolchain, runtime, and libraries. Most of its changes are in the implementation of the toolchain, runtime, and libraries.
As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>. As always, the release maintains the Go 1 <a href="/doc/go1compat.html">promise of compatibility</a>.
We expect almost all Go programs to continue to compile and run as before. We expect almost all Go programs to continue to compile and run as before.
</p> </p>
<p> <p>
OVERVIEW HERE This release improves <a href="#build">caching of built packages</a>,
adds <a href="#test">caching of successful test results</a>,
runs <a href="#test-vet">vet automatically during tests</a>,
and
permits <a href="#cgo">passing string values directly between Go and C using cgo</a>.
A new <a href="#cgo">compiler option whitelist</a> may cause
unexpected <a href="https://golang.org/s/invalidflag"><code>invalid
flag</code></a> errors in code that built successfully with older
releases.
</p> </p>
<h2 id="language">Changes to the language</h2> <h2 id="language">Changes to the language</h2>
<p> <p>
There are no substantive changes to the language. There are no significant changes to the language specification.
</p> </p>
<p><!-- CL 60230 --> <p><!-- CL 60230 -->
A corner case involving shifts by untyped constants has been clarified, A corner case involving shifts of untyped constants has been clarified,
and as a result the compilers have been updated to allow the index expression and as a result the compilers have been updated to allow the index expression
<code>x[1.0</code>&nbsp;<code>&lt;&lt;</code>&nbsp;<code>s]</code> where <code>s</code> is an untyped constant; <code>x[1.0</code>&nbsp;<code>&lt;&lt;</code>&nbsp;<code>s]</code> where <code>s</code> is an unsigned integer;
the <a href="/pkg/go/types/">go/types</a> package already did. the <a href="/pkg/go/types/">go/types</a> package already did.
</p> </p>
@ -64,11 +67,6 @@ in particular <a href="#asm">new instructions in the assembler</a>
and improvements to the code generated by the compilers. and improvements to the code generated by the compilers.
</p> </p>
<p id="darwin">
Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion.
Go 1.11 will require OS X 10.9 Mavericks or later.
</p>
<p id="freebsd"> <p id="freebsd">
As <a href="go1.9#freebsd">announced in the Go 1.9 release notes</a>, As <a href="go1.9#freebsd">announced in the Go 1.9 release notes</a>,
Go 1.10 now requires FreeBSD 10.3 or later; Go 1.10 now requires FreeBSD 10.3 or later;
@ -76,15 +74,9 @@ support for FreeBSD 9.3 has been removed.
</p> </p>
<p id="netbsd"> <p id="netbsd">
Go now runs on NetBSD again, but requires the unreleased NetBSD 8. Go now runs on NetBSD again but requires the unreleased NetBSD 8.
Only <code>GOARCH=amd64</code> running on NetBSD amd64 and <code>GOARCH=386</code> Only <code>GOARCH</code> <code>amd64</code> and <code>386</code> have
running on NetBSD i386 are known to work. 64-bit Go binaries are known to been fixed. The <code>arm</code> port is still broken.
fail on 32-bit NetBSD kernels. <code>GOARCH=arm</code> is untested.
</p>
<p id="openbsd">
Go 1.10 is the last release that will run on OpenBSD 6.0.
Go 1.11 will require OpenBSD 6.2.
</p> </p>
<p id="mips"> <p id="mips">
@ -94,13 +86,34 @@ On 32-bit MIPS systems, the new environment variable settings
hardware instructions or software emulation for floating-point computations. hardware instructions or software emulation for floating-point computations.
</p> </p>
<p id="openbsd">
Go 1.10 is the last release that will run on OpenBSD 6.0.
Go 1.11 will require OpenBSD 6.2.
</p>
<p id="darwin">
Go 1.10 is the last release that will run on OS X 10.8 Mountain Lion or OS X 10.9 Mavericks.
Go 1.11 will require OS X 10.10 Yosemite or later.
</p>
<p id="windows">
Go 1.10 is the last release that will run on Windows XP or Windows Vista.
Go 1.11 will require Windows 7 or later.
</p>
<h2 id="tools">Tools</h2> <h2 id="tools">Tools</h2>
<h3 id="goroot">Default GOROOT &amp; GOTMPDIR</h3> <h3 id="goroot">Default GOROOT &amp; GOTMPDIR</h3>
<p> <p>
TODO: default GOROOT changes in cmd/go If the environment variable <code>$GOROOT</code> is unset,
TODO: computed GOROOT change the go tool previously used the default <code>GOROOT</code>
set during toolchain compilation.
Now, before falling back to that default, the go tool attempts to
deduce <code>GOROOT</code> from its own executable path.
This allows binary distributions to be unpacked anywhere in the
file system and then be used without setting <code>GOROOT</code>
explicitly.
</p> </p>
<p> <p>
@ -146,11 +159,11 @@ back and forth between different branches in a version control system).
The old advice to add the <code>-i</code> flag for speed, as in <code>go</code> <code>build</code> <code>-i</code> The old advice to add the <code>-i</code> flag for speed, as in <code>go</code> <code>build</code> <code>-i</code>
or <code>go</code> <code>test</code> <code>-i</code>, or <code>go</code> <code>test</code> <code>-i</code>,
is no longer necessary: builds run just as fast without <code>-i</code>. is no longer necessary: builds run just as fast without <code>-i</code>.
For more details, see <a href="TODO"><code>go</code> <code>help</code> <code>cache</code></a>. For more details, see <a href="/cmd/go/#hdr-Build_and_test_caching"><code>go</code> <code>help</code> <code>cache</code></a>.
</p> </p>
<p> <p>
The <code>go</code>&nbsp;</code>install</code> command now installs only the The <code>go</code>&nbsp;<code>install</code> command now installs only the
packages and commands listed directly on the command line. packages and commands listed directly on the command line.
For example, <code>go</code> <code>install</code> <code>cmd/gofmt</code> For example, <code>go</code> <code>install</code> <code>cmd/gofmt</code>
installs the gofmt program but not any of the packages on which it depends. installs the gofmt program but not any of the packages on which it depends.
@ -188,7 +201,7 @@ only to command lines using a subset of the
The idiomatic way to bypass test caching is to use <code>-count=1</code>. The idiomatic way to bypass test caching is to use <code>-count=1</code>.
</p> </p>
<p> <p id="test-vet">
The <code>go</code>&nbsp;<code>test</code> command now automatically runs The <code>go</code>&nbsp;<code>test</code> command now automatically runs
<code>go</code> <code>vet</code> on the package being tested, <code>go</code> <code>vet</code> on the package being tested,
to identify significant problems before running the test. to identify significant problems before running the test.
@ -253,7 +266,19 @@ and the <a href="/cmd/test2json/">test2json documentation</a>.
<h3 id="cgo">Cgo</h3> <h3 id="cgo">Cgo</h3>
<p> <p>
Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>;” using a Go type alias, Options specified by cgo using <code>#cgo CFLAGS</code> and the like
are now checked against a whitelist of permitted options.
This closes a security hole in which a downloaded package uses
compiler options like
<span style="white-space: nowrap"><code>-fplugin</code></span>
to run arbitrary code on the machine where it is being built.
This can cause a build error such as <code>invalid flag in #cgo CFLAGS</code>.
For more background, and how to handle this error, see
<a href="https://golang.org/s/invalidflag">https://golang.org/s/invalidflag</a>.
</p>
<p>
Cgo now implements a C typedef like “<code>typedef</code> <code>X</code> <code>Y</code>” using a Go type alias,
so that Go code may use the types <code>C.X</code> and <code>C.Y</code> interchangeably. so that Go code may use the types <code>C.X</code> and <code>C.Y</code> interchangeably.
It also now supports the use of niladic function-like macros. It also now supports the use of niladic function-like macros.
Also, the documentation has been updated to clarify that Also, the documentation has been updated to clarify that
@ -261,9 +286,13 @@ Go structs and Go arrays are not supported in the type signatures of cgo-exporte
</p> </p>
<p> <p>
TODO: CL 70890 "permit passing string values directly between Go and C." Cgo now supports direct access to Go string values from C.
<br> Functions in the C preamble may use the type <code>_GoString_</code>
TODO: CL 66332 "special case C ptr types to use uintptr." to accept a Go string as an argument.
C code may call <code>_GoStringLen</code> and <code>_GoStringPtr</code>
for direct access to the contents of the string.
A value of type <code>_GoString_</code>
may be passed in a call to an exported Go function that takes an argument of Go type <code>string</code>.
</p> </p>
<p> <p>
@ -275,10 +304,37 @@ The new set of environment variables <code>CC_FOR_<i>goos</i>_<i>goarch</i></cod
allows specifying a different default C compiler for each target. allows specifying a different default C compiler for each target.
Note that these variables only apply during toolchain bootstrap, Note that these variables only apply during toolchain bootstrap,
to set the defaults used by the resulting toolchain. to set the defaults used by the resulting toolchain.
Later <code>go</code> <code>build</code> commands refer to the <code>CC</code> environment Later <code>go</code> <code>build</code> commands use the <code>CC</code> environment
variable or else the built-in default. variable or else the built-in default.
</p> </p>
<p>
Cgo now translates some C types that would normally map to a pointer
type in Go, to a <code>uintptr</code> instead. These types include
the <code>CFTypeRef</code> hierarchy in Darwin's CoreFoundation
framework and the <code>jobject</code> hierarchy in Java's JNI
interface.
</p>
<p>
These types must be <code>uintptr</code> on the Go side because they
would otherwise confuse the Go garbage collector; they are sometimes
not really pointers but data structures encoded in a pointer-sized integer.
Pointers to Go memory must not be stored in these <code>uintptr</code> values.
</p>
<p>
Because of this change, values of the affected types need to be
zero-initialized with the constant <code>0</code> instead of the
constant <code>nil</code>. Go 1.10 provides <code>gofix</code>
modules to help with that rewrite:
</p>
<pre>
go tool fix -r cftype &lt;pkg&gt;
go tool fix -r jni &lt;pkg&gt;
</pre>
<p> <p>
For more details, see the <a href="/cmd/cgo/">cgo documentation</a>. For more details, see the <a href="/cmd/cgo/">cgo documentation</a>.
</p> </p>
@ -336,8 +392,9 @@ without the binary that produced the profile.
</p> </p>
<p> <p>
The <a href="/cmd/pprof/"><code>go</code>&nbsp;<code>tool</code>&nbsp;<code>pprof</code></a> profile visualizer has been updated to The <a href="/cmd/pprof/"><code>go</code>&nbsp;<code>tool</code>&nbsp;<code>pprof</code></a>
the latest version from <a href="https://github.com/google/pprof">github.com/google/pprof</a>, profile visualizer has been updated to git version 9e20b5b (2017-11-08)
from <a href="https://github.com/google/pprof">github.com/google/pprof</a>,
which includes an updated web interface. which includes an updated web interface.
</p> </p>
@ -383,17 +440,10 @@ a repository is not “properly formatted” is inherently fragile and not recom
<p> <p>
If multiple programs must agree about which version of gofmt is used to format a source file, If multiple programs must agree about which version of gofmt is used to format a source file,
we recommend that they do this by arranging to invoke the same gofmt binary. we recommend that they do this by arranging to invoke the same gofmt binary.
For example, in the Go open source repository, we arrange for goimports and For example, in the Go open source repository, our Git pre-commit hook is written in Go
our Git pre-commit hook to agree about source code formatting by having both and could import <code>go/format</code> directly, but instead it invokes the <code>gofmt</code>
invoke the gofmt binary found in the current path. binary found in the current path, so that the pre-commit hook need not be recompiled
TODO: Make goimports actually do that. #22695. each time <code>gofmt</code> changes.
As another example, inside Google we arrange that source code presubmit
checks run a gofmt binary maintained at a fixed path in a shared, distributed file system;
that on engineering workstations <code>/usr/bin/gofmt</code>
is a symbolic link to that same path;
and that all editor integrations used for Google development
explicitly invoke /usr/bin/gofmt.
TODO: TMI?
</p> </p>
<h3 id="compiler">Compiler Toolchain</h3> <h3 id="compiler">Compiler Toolchain</h3>
@ -412,10 +462,10 @@ and each package is now presented as its own DWARF compilation unit.
<p> <p>
The various <a href="https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit">build modes</a> The various <a href="https://docs.google.com/document/d/1nr-TQHw_er6GOQRsF6T43GGhFDelrAP0NqSS_00RgZQ/edit">build modes</a>
has been ported to more systems. have been ported to more systems.
Specifically, <code>c-shared</code> now works on <code>linux/ppc64le</code>, <code>windows/386</code>, and <code>windows/amd64</code>; Specifically, <code>c-shared</code> now works on <code>linux/ppc64le</code>, <code>windows/386</code>, and <code>windows/amd64</code>;
<code>pie</code> now works on <code>darwin/amd64</code> and also forces the use of external linking on all systems; <code>pie</code> now works on <code>darwin/amd64</code> and also forces the use of external linking on all systems;
and <code>plugin</code> now works on <code>linux/ppc64le</code>. and <code>plugin</code> now works on <code>linux/ppc64le</code> and <code>darwin/amd64</code>.
</p> </p>
<p> <p>
@ -517,7 +567,11 @@ to avoid clearing the condition flags unexpectedly.
<h3 id="gccgo">Gccgo</h3> <h3 id="gccgo">Gccgo</h3>
<p> <p>
TODO: Words about GCC 8 and Go 1.10. Due to the alignment of Go's semiannual release schedule with GCC's
annual release schedule,
GCC release 7 contains the Go 1.8.3 version of gccgo.
We expect that the next release, GCC 8, will contain the Go 1.10
version of gccgo.
</p> </p>
<h2 id="runtime">Runtime</h2> <h2 id="runtime">Runtime</h2>
@ -537,7 +591,7 @@ Now, the calls nest: if <code>LockOSThread</code> is called multiple times,
in order to unlock the thread. in order to unlock the thread.
Existing code that was careful not to nest these calls will remain correct. Existing code that was careful not to nest these calls will remain correct.
Existing code that incorrectly assumed the calls nested will become correct. Existing code that incorrectly assumed the calls nested will become correct.
Most uses of these functions in public Go source falls into the second category. Most uses of these functions in public Go source code falls into the second category.
</p> </p>
<p> <p>
@ -555,12 +609,23 @@ optimization decisions and implementation details.
</p> </p>
<p> <p>
There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting. The garbage collector has been modified to reduce its impact on allocation latency.
(In Go 1.9 the limit was 1024.) It now uses a smaller fraction of the overall CPU when running, but it may run more of the time.
The total CPU consumed by the garbage collector has not changed significantly.
</p> </p>
<p> <p>
TODO: Anything about CL 59970: "runtime: separate soft and hard heap limits"? The <a href="/pkg/runtime/#GOROOT"><code>GOROOT</code></a> function
now defaults (when the <code>$GOROOT</code> environment variable is not set)
to the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
at the time the calling program was compiled.
Previously it used the <code>GOROOT</code> or <code>GOROOT_FINAL</code> in effect
at the time the toolchain that compiled the calling program was compiled.
</p>
<p>
There is no longer a limit on the <a href="/pkg/runtime/#GOMAXPROCS"><code>GOMAXPROCS</code></a> setting.
(In Go 1.9 the limit was 1024.)
</p> </p>
<h2 id="performance">Performance</h2> <h2 id="performance">Performance</h2>
@ -689,9 +754,9 @@ The
<a href="/pkg/bytes/#Split"><code>Split</code></a>, <a href="/pkg/bytes/#Split"><code>Split</code></a>,
and and
<a href="/pkg/bytes/#SplitAfter"><code>SplitAfter</code></a> <a href="/pkg/bytes/#SplitAfter"><code>SplitAfter</code></a>
each already returned slices pointing into the same underlying array as its input. functions have always returned subslices of their inputs.
Go 1.10 changes each of the returned subslices to have capacity equal to its length, Go 1.10 changes each returned subslice to have capacity equal to its length,
so that appending to a subslice will not overwrite adjacent data in the original input. so that appending to one cannot overwrite adjacent data in the original input.
</p> </p>
</dl> </dl>
@ -717,13 +782,13 @@ them unless explicitly advertised.
<dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt> <dl id="crypto/x509"><dt><a href="/pkg/crypto/x509/">crypto/x509</a></dt>
<dd> <dd>
<p> <p>
Leaf certificate validation now enforces the name constraints for all <a href="/pkg/crypto/x509/#Certificate.Verify"><code>Certificate.Verify</code></a>
now enforces the name constraints for all
names contained in the certificate, not just the one name that a client has asked about. names contained in the certificate, not just the one name that a client has asked about.
Extended key usage restrictions are similarly now checked all at once. Extended key usage restrictions are similarly now checked all at once.
As a result, after a certificate has been validated, now it can be trusted in its entirety. As a result, after a certificate has been validated, now it can be trusted in its entirety.
It is no longer necessary to revalidate the certificate for each additional name It is no longer necessary to revalidate the certificate for each additional name
or key usage. or key usage.
TODO: Link to docs that may not exist yet.
</p> </p>
<p> <p>
@ -731,7 +796,8 @@ Parsed certificates also now report URI names and IP, email, and URI constraints
<a href="/pkg/crypto/x509/#Certificate"><code>Certificate</code></a> fields <a href="/pkg/crypto/x509/#Certificate"><code>Certificate</code></a> fields
<code>URIs</code>, <code>PermittedIPRanges</code>, <code>ExcludedIPRanges</code>, <code>URIs</code>, <code>PermittedIPRanges</code>, <code>ExcludedIPRanges</code>,
<code>PermittedEmailAddresses</code>, <code>ExcludedEmailAddresses</code>, <code>PermittedEmailAddresses</code>, <code>ExcludedEmailAddresses</code>,
<code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>. <code>PermittedURIDomains</code>, and <code>ExcludedURIDomains</code>. Certificates with
invalid values for those fields are now rejected.
</p> </p>
<p> <p>
@ -760,6 +826,13 @@ formats the X.509 distinguished name in the standard RFC 2253 format.
<dl id="database/sql/driver"><dt><a href="/pkg/database/sql/driver/">database/sql/driver</a></dt> <dl id="database/sql/driver"><dt><a href="/pkg/database/sql/driver/">database/sql/driver</a></dt>
<dd> <dd>
<p> <p>
Drivers that currently hold on to the destination buffer provided by
<a href="/pkg/database/sql/driver/#Rows.Next"><code>driver.Rows.Next</code></a> should ensure they no longer
write to a buffer assigned to the destination array outside of that call.
Drivers must be careful that underlying buffers are not modified when closing
<a href="/pkg/database/sql/driver/#Rows"><code>driver.Rows</code></a>.
</p>
<p>
Drivers that want to construct a <a href="/pkg/database/sql/#DB"><code>sql.DB</code></a> for Drivers that want to construct a <a href="/pkg/database/sql/#DB"><code>sql.DB</code></a> for
their clients can now implement the <a href="/pkg/database/sql/driver/#Connector"><code>Connector</code></a> interface their clients can now implement the <a href="/pkg/database/sql/driver/#Connector"><code>Connector</code></a> interface
and call the new <a href="/pkg/database/sql/#OpenDB"><code>sql.OpenDB</code></a> function, and call the new <a href="/pkg/database/sql/#OpenDB"><code>sql.OpenDB</code></a> function,
@ -1008,12 +1081,10 @@ now implement those interfaces.
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt> <dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
<dd> <dd>
<p> <p>
The new actions <code>{{"{{break}}"}}</code> and <code>{{"{{continue}}"}}</code> The new <a href="/pkg/html/template#Srcset"><code>Srcset</code></a> content
break out of the innermost <code>{{"{{range"}}</code>&nbsp;...<code>}}</code> loop, type allows for proper handling of values within the
like the corresponding Go statements. <a href="https://w3c.github.io/html/semantics-embedded-content.html#element-attrdef-img-srcset"><code>srcset</code></a>
</p> attribute of <code>img</code> tags.
<p>
TODO: something about the AddParseTree problem (#21844).
</p> </p>
</dl> </dl>
@ -1042,11 +1113,11 @@ compute square roots.
<dd> <dd>
<p> <p>
Branch cuts and other boundary cases in Branch cuts and other boundary cases in
<a href="/pkg/math/cmplx/#Asin"><code>Asin<code></a>, <a href="/pkg/math/cmplx/#Asin"><code>Asin</code></a>,
<a href="/pkg/math/cmplx/#Asinh"><code>Asinh<code></a>, <a href="/pkg/math/cmplx/#Asinh"><code>Asinh</code></a>,
<a href="/pkg/math/cmplx/#Atan"><code>Atan<code></a>, <a href="/pkg/math/cmplx/#Atan"><code>Atan</code></a>,
and and
<a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt<code></a> <a href="/pkg/math/cmplx/#Sqrt"><code>Sqrt</code></a>
have been corrected to match the definitions used in the C99 standard. have been corrected to match the definitions used in the C99 standard.
</p> </p>
</dl> </dl>
@ -1154,14 +1225,11 @@ The content-serving handlers also now omit the <code>Content-Type</code> header
if passed an invalid (non-3-digit) status code. if passed an invalid (non-3-digit) status code.
</p> </p>
<p> <p>
<a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response. <!-- CL 46631 -->
The <code>Server</code> will no longer add an implicit Content-Type when a <code>Handler</code> does not write any output.
</p> </p>
</dl>
<dl id="net/http/httputil"><dt><a href="/pkg/net/http/httputil/">net/http/httputil</a></dt>
<dd>
<p> <p>
TODO: ReverseProxy and back end errors and ModifyResponse. <a href="/pkg/net/http/#Redirect"><code>Redirect</code></a> now sets the <code>Content-Type</code> header before writing its HTTP response.
</p> </p>
</dl> </dl>
@ -1200,7 +1268,7 @@ were not indented.
<dd> <dd>
<p> <p>
<a href="/pkg/net/url/#ResolveReference"><code>ResolveReference</code></a> <a href="/pkg/net/url/#ResolveReference"><code>ResolveReference</code></a>
now preseves multiple leading slashes in the target URL. now preserves multiple leading slashes in the target URL.
Previously it rewrote multiple leading slashes to a single slash, Previously it rewrote multiple leading slashes to a single slash,
which resulted in the <a href="/pkg/net/http/#Client"><code>http.Client</code></a> which resulted in the <a href="/pkg/net/http/#Client"><code>http.Client</code></a>
following certain redirects incorrectly. following certain redirects incorrectly.
@ -1249,6 +1317,10 @@ and
that allow setting I/O deadlines when the that allow setting I/O deadlines when the
underlying file descriptor supports non-blocking I/O operations. underlying file descriptor supports non-blocking I/O operations.
The definition of these methods matches those in <a href="/pkg/net/#Conn"><code>net.Conn</code></a>. The definition of these methods matches those in <a href="/pkg/net/#Conn"><code>net.Conn</code></a>.
If an I/O method fails due to missing a deadline, it will return a
timeout error; the
new <a href="/pkg/os/#IsTimeout"><code>IsTimeout</code></a> function
reports whether an error represents a timeout.
</p> </p>
<p> <p>
@ -1257,7 +1329,7 @@ Also matching <code>net.Conn</code>,
<a href="/pkg/os/#File.Close"><code>Close</code></a> method <a href="/pkg/os/#File.Close"><code>Close</code></a> method
now guarantee that when <code>Close</code> returns, now guarantee that when <code>Close</code> returns,
the underlying file descriptor has been closed. the underlying file descriptor has been closed.
(In earlier releases, like for <code>net.Conn</code>'s, (In earlier releases,
if the <code>Close</code> stopped pending I/O if the <code>Close</code> stopped pending I/O
in other goroutines, the closing of the file descriptor could happen in one of those in other goroutines, the closing of the file descriptor could happen in one of those
goroutines shortly after <code>Close</code> returned.) goroutines shortly after <code>Close</code> returned.)
@ -1286,7 +1358,7 @@ in the corresponding <a href="/pkg/reflect/#StructField">StructField</a>,
with the result that for those fields, with the result that for those fields,
and <a href="/pkg/reflect/#Value.CanSet"><code>Value.CanSet</code></a> and <a href="/pkg/reflect/#Value.CanSet"><code>Value.CanSet</code></a>
incorrectly returned true and incorrectly returned true and
and <a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a> <a href="/pkg/reflect/#Value.Set"><code>Value.Set</code></a>
incorrectly succeeded. incorrectly succeeded.
The underlying metadata has been corrected; The underlying metadata has been corrected;
for those fields, for those fields,
@ -1297,7 +1369,6 @@ that could previously unmarshal into such fields
but no longer can. but no longer can.
For example, see the <a href="#encoding/json"><code>encoding/json</code> notes</a>. For example, see the <a href="#encoding/json"><code>encoding/json</code> notes</a>.
</p> </p>
</p>
</dl> </dl>
<dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt> <dl id="runtime/pprof"><dt><a href="/pkg/runtime/pprof/">runtime/pprof</a></dt>
@ -1351,15 +1422,6 @@ is now implemented.
</p> </p>
</dl> </dl>
<dl id="text/template"><dt><a href="/pkg/text/template/">text/template</a></dt>
<dd>
<p>
The new actions <code>{{"{{break}}"}}</code> and <code>{{"{{continue}}"}}</code>
break out of the innermost <code>{{"{{range"}}</code>&nbsp;...<code>}}</code> loop,
like the corresponding Go statements.
</p>
</dl>
<dl id="time"><dt><a href="/pkg/time/">time</a></dt> <dl id="time"><dt><a href="/pkg/time/">time</a></dt>
<dd> <dd>
<p> <p>
@ -1378,7 +1440,7 @@ allows conversion of IANA time zone file data to a <a href="/pkg/time/#Location"
<dd> <dd>
<p> <p>
The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated The <a href="/pkg/unicode/"><code>unicode</code></a> package and associated
support throughout the system has been upgraded from version 9.0 to support throughout the system has been upgraded from Unicode 9.0 to
<a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>, <a href="http://www.unicode.org/versions/Unicode10.0.0/">Unicode 10.0</a>,
which adds 8,518 new characters, including four new scripts, one new property, which adds 8,518 new characters, including four new scripts, one new property,
a Bitcoin currency symbol, and 56 new emoji. a Bitcoin currency symbol, and 56 new emoji.

View file

@ -266,7 +266,7 @@ is now an error.
<p> <p>
On the ARM, the toolchain supports "external linking", which On the ARM, the toolchain supports "external linking", which
is a step towards being able to build shared libraries with the gc is a step towards being able to build shared libraries with the gc
tool chain and to provide dynamic linking support for environments toolchain and to provide dynamic linking support for environments
in which that is necessary. in which that is necessary.
</p> </p>

View file

@ -11,7 +11,7 @@ The latest Go release, version 1.3, arrives six months after 1.2,
and contains no language changes. and contains no language changes.
It focuses primarily on implementation work, providing It focuses primarily on implementation work, providing
precise garbage collection, precise garbage collection,
a major refactoring of the compiler tool chain that results in a major refactoring of the compiler toolchain that results in
faster builds, especially for large projects, faster builds, especially for large projects,
significant performance improvements across the board, significant performance improvements across the board,
and support for DragonFly BSD, Solaris, Plan 9 and Google's Native Client architecture (NaCl). and support for DragonFly BSD, Solaris, Plan 9 and Google's Native Client architecture (NaCl).
@ -285,7 +285,7 @@ building and linking with a shared library.
<h3 id="gc_flag">Command-line flag parsing</h3> <h3 id="gc_flag">Command-line flag parsing</h3>
<p> <p>
In the gc tool chain, the assemblers now use the In the gc toolchain, the assemblers now use the
same command-line flag parsing rules as the Go flag package, a departure same command-line flag parsing rules as the Go flag package, a departure
from the traditional Unix flag parsing. from the traditional Unix flag parsing.
This may affect scripts that invoke the tool directly. This may affect scripts that invoke the tool directly.

View file

@ -2035,4 +2035,4 @@ They are available for many combinations of architecture and operating system
Installation details are described on the Installation details are described on the
<a href="/doc/install">Getting Started</a> page, while <a href="/doc/install">Getting Started</a> page, while
the distributions themselves are listed on the the distributions themselves are listed on the
<a href="https://golang.org/dl/">downloads page</a>. <a href="/dl/">downloads page</a>.

View file

@ -190,8 +190,8 @@ For details and background, see
<h2 id="tools">Tools</h2> <h2 id="tools">Tools</h2>
<p> <p>
Finally, the Go tool chain (compilers, linkers, build tools, and so Finally, the Go toolchain (compilers, linkers, build tools, and so
on) are under active development and may change behavior. This on) is under active development and may change behavior. This
means, for instance, that scripts that depend on the location and means, for instance, that scripts that depend on the location and
properties of the tools may be broken by a point release. properties of the tools may be broken by a point release.
</p> </p>

View file

@ -479,6 +479,15 @@ as when hosting an untrusted program, the implementation could interlock
map access. map access.
</p> </p>
<p>
Map access is unsafe only when updates are occurring.
As long as all goroutines are only reading—looking up elements in the map,
including iterating through it using a
<code>for</code> <code>range</code> loop—and not changing the map
by assigning to elements or doing deletions,
it is safe for them to access the map concurrently without synchronization.
</p>
<h3 id="language_changes"> <h3 id="language_changes">
Will you accept my language change?</h3> Will you accept my language change?</h3>
@ -1088,24 +1097,27 @@ The <code>go get</code> command therefore uses HTTPS for safety.
</p> </p>
<p> <p>
If you use <code>git</code> and prefer to push changes through SSH using your existing key <code>Git</code> can be configured to authenticate over HTTPS or to use SSH in place of HTTPS.
it's easy to work around this. For GitHub, try one of these solutions: To authenticate over HTTPS, you can add a line
to the <code>$HOME/.netrc</code> file that git consults:
</p> </p>
<ul>
<li>Manually clone the repository in the expected package directory:
<pre> <pre>
$ cd src/github.com/username machine github.com login <i>USERNAME</i> password <i>APIKEY</i>
$ git clone git@github.com:username/package.git
</pre> </pre>
</li> <p>
<li>Force <code>git push</code> to use the <code>SSH</code> protocol by appending For GitHub accounts, the password can be a
these two lines to <code>~/.gitconfig</code>: <a href="https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/">personal access token</a>.
</p>
<p>
<code>Git</code> can also be configured to use SSH in place of HTTPS for URLs matching a given prefix.
For example, to use SSH for all GitHub access,
add these lines to your <code>~/.gitconfig</code>:
</p>
<pre> <pre>
[url "git@github.com:"] [url "ssh://git@github.com/"]
pushInsteadOf = https://github.com/ insteadOf = https://github.com/
</pre> </pre>
</li>
</ul>
<h3 id="get_version"> <h3 id="get_version">
How should I manage package versions using "go get"?</h3> How should I manage package versions using "go get"?</h3>
@ -1842,19 +1854,20 @@ supported by recent modifications to the gold linker.
Why is my trivial program such a large binary?</h3> Why is my trivial program such a large binary?</h3>
<p> <p>
The linker in the <code>gc</code> tool chain The linker in the <code>gc</code> toolchain
creates statically-linked binaries by default. All Go binaries therefore include the Go creates statically-linked binaries by default.
All Go binaries therefore include the Go
run-time, along with the run-time type information necessary to support dynamic run-time, along with the run-time type information necessary to support dynamic
type checks, reflection, and even panic-time stack traces. type checks, reflection, and even panic-time stack traces.
</p> </p>
<p> <p>
A simple C "hello, world" program compiled and linked statically using gcc A simple C "hello, world" program compiled and linked statically using
on Linux is around 750 kB, gcc on Linux is around 750 kB, including an implementation of
including an implementation of <code>printf</code>. <code>printf</code>.
An equivalent Go program using <code>fmt.Printf</code> An equivalent Go program using
is around 1.5 MB, but <code>fmt.Printf</code> weighs a couple of megabytes, but that includes
that includes more powerful run-time support and type information. more powerful run-time support and type and debugging information.
</p> </p>
<h3 id="unused_variables_and_imports"> <h3 id="unused_variables_and_imports">
@ -1922,6 +1935,26 @@ eliminating the unused imports issue in practice.
This program is easily connected to most editors to run automatically when a Go source file is written. This program is easily connected to most editors to run automatically when a Go source file is written.
</p> </p>
<h3 id="virus">
Why does my virus-scanning software think my Go distribution or compiled binary is infected?</h3>
<p>
This is a common occurrence, especially on Windows machines, and is almost always a false positive.
Commercial virus scanning programs are often confused by the structure of Go binaries, which
they don't see as often as those compiled from other languages.
</p>
<p>
If you've just installed the Go distribution and the system reports it is infected, that's certainly a mistake.
To be really thorough, you can verify the download by comparing the checksum with those on the
<a href="https://golang.org/dl/">downloads page</a>.
</p>
<p>
In any case, if you believe the report is in error, please report a bug to the supplier of your virus scanner.
Maybe in time virus scanners can learn to understand Go programs.
</p>
<h2 id="Performance">Performance</h2> <h2 id="Performance">Performance</h2>
<h3 id="Why_does_Go_perform_badly_on_benchmark_x"> <h3 id="Why_does_Go_perform_badly_on_benchmark_x">

View file

@ -1,6 +1,6 @@
<!--{ <!--{
"Title": "The Go Programming Language Specification", "Title": "The Go Programming Language Specification",
"Subtitle": "Version of October 25, 2017", "Subtitle": "Version of May 9, 2018",
"Path": "/ref/spec" "Path": "/ref/spec"
}--> }-->
@ -694,9 +694,8 @@ TypeLit = ArrayType | StructType | PointerType | FunctionType | InterfaceType
</pre> </pre>
<p> <p>
Named instances of the boolean, numeric, and string types are The language <a href="#Predeclared_identifiers">predeclares</a> certain type names.
<a href="#Predeclared_identifiers">predeclared</a>. Others are introduced with <a href="#Type_declarations">type declarations</a>.
Other named types are introduced with <a href="#Type_declarations">type declarations</a>.
<i>Composite types</i>&mdash;array, struct, pointer, function, <i>Composite types</i>&mdash;array, struct, pointer, function,
interface, slice, map, and channel types&mdash;may be constructed using interface, slice, map, and channel types&mdash;may be constructed using
type literals. type literals.
@ -1025,8 +1024,8 @@ of a struct except that they cannot be used as field names in
</p> </p>
<p> <p>
Given a struct type <code>S</code> and a type named <code>T</code>, Given a struct type <code>S</code> and a <a href="#Type_definitions">defined type</a>
promoted methods are included in the method set of the struct as follows: <code>T</code>, promoted methods are included in the method set of the struct as follows:
</p> </p>
<ul> <ul>
<li> <li>
@ -1453,9 +1452,9 @@ components have identical types. In detail:
<a href="#Exported_identifiers">Non-exported</a> method names from different <a href="#Exported_identifiers">Non-exported</a> method names from different
packages are always different. The order of the methods is irrelevant.</li> packages are always different. The order of the methods is irrelevant.</li>
<li>Two map types are identical if they have identical key and value types.</li> <li>Two map types are identical if they have identical key and element types.</li>
<li>Two channel types are identical if they have identical value types and <li>Two channel types are identical if they have identical element types and
the same direction.</li> the same direction.</li>
</ul> </ul>
@ -1495,7 +1494,7 @@ A2 and struct{ a, b int }
A3 and int A3 and int
A4, func(int, float64) *[]string, and A5 A4, func(int, float64) *[]string, and A5
B0, B0, and C0 B0 and C0
[]int and []int []int and []int
struct{ a, b *T5 } and struct{ a, b *T5 } struct{ a, b *T5 } and struct{ a, b *T5 }
func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5 func(x int, y float64) *[]string, func(int, float64) (result *[]string), and A5
@ -2149,9 +2148,8 @@ to a function.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
FunctionDecl = "func" FunctionName ( Function | Signature ) . FunctionDecl = "func" FunctionName Signature [ FunctionBody ] .
FunctionName = identifier . FunctionName = identifier .
Function = Signature FunctionBody .
FunctionBody = Block . FunctionBody = Block .
</pre> </pre>
@ -2197,7 +2195,7 @@ and associates the method with the receiver's <i>base type</i>.
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
MethodDecl = "func" Receiver MethodName ( Function | Signature ) . MethodDecl = "func" Receiver MethodName Signature [ FunctionBody ] .
Receiver = Parameters . Receiver = Parameters .
</pre> </pre>
@ -2519,7 +2517,7 @@ A function literal represents an anonymous <a href="#Function_declarations">func
</p> </p>
<pre class="ebnf"> <pre class="ebnf">
FunctionLit = "func" Function . FunctionLit = "func" Signature FunctionBody .
</pre> </pre>
<pre> <pre>
@ -2643,8 +2641,8 @@ expression is illegal.
</li> </li>
<li> <li>
As an exception, if the type of <code>x</code> is a named pointer type As an exception, if the type of <code>x</code> is a <a href="#Type_definitions">defined</a>
and <code>(*x).f</code> is a valid selector expression denoting a field pointer type and <code>(*x).f</code> is a valid selector expression denoting a field
(but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>. (but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>.
</li> </li>
@ -3033,11 +3031,11 @@ For <code>a</code> of <a href="#Map_types">map type</a> <code>M</code>:
<a href="#Assignability">assignable</a> <a href="#Assignability">assignable</a>
to the key type of <code>M</code></li> to the key type of <code>M</code></li>
<li>if the map contains an entry with key <code>x</code>, <li>if the map contains an entry with key <code>x</code>,
<code>a[x]</code> is the map value with key <code>x</code> <code>a[x]</code> is the map element with key <code>x</code>
and the type of <code>a[x]</code> is the value type of <code>M</code></li> and the type of <code>a[x]</code> is the element type of <code>M</code></li>
<li>if the map is <code>nil</code> or does not contain such an entry, <li>if the map is <code>nil</code> or does not contain such an entry,
<code>a[x]</code> is the <a href="#The_zero_value">zero value</a> <code>a[x]</code> is the <a href="#The_zero_value">zero value</a>
for the value type of <code>M</code></li> for the element type of <code>M</code></li>
</ul> </ul>
<p> <p>
@ -3053,7 +3051,6 @@ used in an <a href="#Assignments">assignment</a> or initialization of the specia
v, ok = a[x] v, ok = a[x]
v, ok := a[x] v, ok := a[x]
var v, ok = a[x] var v, ok = a[x]
var v, ok T = a[x]
</pre> </pre>
<p> <p>
@ -3558,9 +3555,10 @@ with <code>x / y</code> truncated towards zero
</pre> </pre>
<p> <p>
As an exception to this rule, if the dividend <code>x</code> is the most The one exception to this rule is that if the dividend <code>x</code> is
negative value for the int type of <code>x</code>, the quotient the most negative value for the int type of <code>x</code>, the quotient
<code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>). <code>q = x / -1</code> is equal to <code>x</code> (and <code>r = 0</code>)
due to two's-complement <a href="#Integer_overflow">integer overflow</a>:
</p> </p>
<pre> <pre>
@ -3619,15 +3617,15 @@ For unsigned integer values, the operations <code>+</code>,
computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of computed modulo 2<sup><i>n</i></sup>, where <i>n</i> is the bit width of
the <a href="#Numeric_types">unsigned integer</a>'s type. the <a href="#Numeric_types">unsigned integer</a>'s type.
Loosely speaking, these unsigned integer operations Loosely speaking, these unsigned integer operations
discard high bits upon overflow, and programs may rely on ``wrap around''. discard high bits upon overflow, and programs may rely on "wrap around".
</p> </p>
<p> <p>
For signed integers, the operations <code>+</code>, For signed integers, the operations <code>+</code>,
<code>-</code>, <code>*</code>, and <code>&lt;&lt;</code> may legally <code>-</code>, <code>*</code>, <code>/</code>, and <code>&lt;&lt;</code> may legally
overflow and the resulting value exists and is deterministically defined overflow and the resulting value exists and is deterministically defined
by the signed integer representation, the operation, and its operands. by the signed integer representation, the operation, and its operands.
No exception is raised as a result of overflow. A No exception is raised as a result of overflow.
compiler may not optimize code under the assumption that overflow does A compiler may not optimize code under the assumption that overflow does
not occur. For instance, it may not assume that <code>x &lt; x + 1</code> is always true. not occur. For instance, it may not assume that <code>x &lt; x + 1</code> is always true.
</p> </p>
@ -4162,11 +4160,6 @@ operands and are evaluated at compile time.
Untyped boolean, numeric, and string constants may be used as operands Untyped boolean, numeric, and string constants may be used as operands
wherever it is legal to use an operand of boolean, numeric, or string type, wherever it is legal to use an operand of boolean, numeric, or string type,
respectively. respectively.
Except for shift operations, if the operands of a binary operation are
different kinds of untyped constants, the operation and, for non-boolean operations, the result use
the kind that appears later in this list: integer, rune, floating-point, complex.
For example, an untyped integer constant divided by an
untyped complex constant yields an untyped complex constant.
</p> </p>
<p> <p>
@ -4176,9 +4169,17 @@ an untyped boolean constant. If the left operand of a constant
result is an integer constant; otherwise it is a constant of the same result is an integer constant; otherwise it is a constant of the same
type as the left operand, which must be of type as the left operand, which must be of
<a href="#Numeric_types">integer type</a>. <a href="#Numeric_types">integer type</a>.
Applying all other operators to untyped constants results in an untyped </p>
constant of the same kind (that is, a boolean, integer, floating-point,
complex, or string constant). <p>
Any other operation on untyped constants results in an untyped constant of the
same kind; that is, a boolean, integer, floating-point, complex, or string
constant.
If the untyped operands of a binary operation (other than a shift) are of
different kinds, the result is of the operand's kind that appears later in this
list: integer, rune, floating-point, complex.
For example, an untyped integer constant divided by an
untyped complex constant yields an untyped complex constant.
</p> </p>
<pre> <pre>
@ -4356,7 +4357,9 @@ SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | S
<h3 id="Terminating_statements">Terminating statements</h3> <h3 id="Terminating_statements">Terminating statements</h3>
<p> <p>
A terminating statement is one of the following: A <i>terminating statement</i> prevents execution of all statements that lexically
appear after it in the same <a href="#Blocks">block</a>. The following statements
are terminating:
</p> </p>
<ol> <ol>
@ -5120,7 +5123,7 @@ for i, s := range a {
} }
var key string var key string
var val interface {} // value type of m is assignable to val var val interface {} // element type of m is assignable to val
m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6} m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
for key, val = range m { for key, val = range m {
h(key, val) h(key, val)

View file

@ -24,7 +24,7 @@ packages, though, read on.
<div class="detail"> <div class="detail">
<p> <p>
There are two official Go compiler tool chains. There are two official Go compiler toolchains.
This document focuses on the <code>gc</code> Go This document focuses on the <code>gc</code> Go
compiler and tools. compiler and tools.
For information on how to work on <code>gccgo</code>, a more traditional For information on how to work on <code>gccgo</code>, a more traditional
@ -119,7 +119,7 @@ Go does not support CentOS 6 on these systems.
<h2 id="go14">Install Go compiler binaries</h2> <h2 id="go14">Install Go compiler binaries</h2>
<p> <p>
The Go tool chain is written in Go. To build it, you need a Go compiler installed. The Go toolchain is written in Go. To build it, you need a Go compiler installed.
The scripts that do the initial build of the tools look for an existing Go tool The scripts that do the initial build of the tools look for an existing Go tool
chain in <code>$GOROOT_BOOTSTRAP</code>. chain in <code>$GOROOT_BOOTSTRAP</code>.
If unset, the default value of <code>GOROOT_BOOTSTRAP</code> If unset, the default value of <code>GOROOT_BOOTSTRAP</code>
@ -127,26 +127,26 @@ is <code>$HOME/go1.4</code>.
</p> </p>
<p> <p>
There are many options for the bootstrap tool chain. There are many options for the bootstrap toolchain.
After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the After obtaining one, set <code>GOROOT_BOOTSTRAP</code> to the
directory containing the unpacked tree. directory containing the unpacked tree.
For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be For example, <code>$GOROOT_BOOTSTRAP/bin/go</code> should be
the <code>go</code> command binary for the bootstrap tool chain. the <code>go</code> command binary for the bootstrap toolchain.
</p> </p>
<p> <p>
To use a binary release as a bootstrap tool chain, see To use a binary release as a bootstrap toolchain, see
<a href="/dl/">the downloads page</a> or use any other <a href="/dl/">the downloads page</a> or use any other
packaged Go distribution. packaged Go distribution.
</p> </p>
<p> <p>
To build a bootstrap tool chain from source, use To build a bootstrap toolchain from source, use
either the git branch <code>release-branch.go1.4</code> or either the git branch <code>release-branch.go1.4</code> or
<a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>, <a href="https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz">go1.4-bootstrap-20171003.tar.gz</a>,
which contains the Go 1.4 source code plus accumulated fixes which contains the Go 1.4 source code plus accumulated fixes
to keep the tools running on newer operating systems. to keep the tools running on newer operating systems.
(Go 1.4 was the last distribution in which the tool chain was written in C.) (Go 1.4 was the last distribution in which the toolchain was written in C.)
After unpacking the Go 1.4 source, <code>cd</code> to After unpacking the Go 1.4 source, <code>cd</code> to
the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in the <code>src</code> subdirectory, set <code>CGO_ENABLED=0</code> in
the environment, and run <code>make.bash</code> (or, the environment, and run <code>make.bash</code> (or,
@ -154,7 +154,7 @@ on Windows, <code>make.bat</code>).
</p> </p>
<p> <p>
To cross-compile a bootstrap tool chain from source, which is To cross-compile a bootstrap toolchain from source, which is
necessary on systems Go 1.4 did not target (for necessary on systems Go 1.4 did not target (for
example, <code>linux/ppc64le</code>), install Go on a different system example, <code>linux/ppc64le</code>), install Go on a different system
and run <a href="/src/bootstrap.bash">bootstrap.bash</a>. and run <a href="/src/bootstrap.bash">bootstrap.bash</a>.
@ -446,6 +446,7 @@ defaults to the parent of the directory where <code>all.bash</code> was run.
There is no need to set this unless you want to switch between multiple There is no need to set this unless you want to switch between multiple
local copies of the repository. local copies of the repository.
</p> </p>
</li>
<li><code>$GOROOT_FINAL</code> <li><code>$GOROOT_FINAL</code>
<p> <p>
@ -456,12 +457,14 @@ If you want to build the Go tree in one location
but move it elsewhere after the build, set but move it elsewhere after the build, set
<code>$GOROOT_FINAL</code> to the eventual location. <code>$GOROOT_FINAL</code> to the eventual location.
</p> </p>
</li>
<li><code>$GOOS</code> and <code>$GOARCH</code> <li><code>$GOOS</code> and <code>$GOARCH</code>
<p> <p>
The name of the target operating system and compilation architecture. The name of the target operating system and compilation architecture.
These default to the values of <code>$GOHOSTOS</code> and These default to the values of <code>$GOHOSTOS</code> and
<code>$GOHOSTARCH</code> respectively (described below). <code>$GOHOSTARCH</code> respectively (described below).
</li>
<p> <p>
Choices for <code>$GOOS</code> are Choices for <code>$GOOS</code> are
@ -582,6 +585,7 @@ The name of the host operating system and compilation architecture.
These default to the local system's operating system and These default to the local system's operating system and
architecture. architecture.
</p> </p>
</li>
<p> <p>
Valid choices are the same as for <code>$GOOS</code> and Valid choices are the same as for <code>$GOOS</code> and
@ -600,6 +604,7 @@ directory to your <code>$PATH</code>, so you can use the tools.
If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a> If <code>$GOBIN</code> is set, the <a href="/cmd/go">go command</a>
installs all commands there. installs all commands there.
</p> </p>
</li>
<li><code>$GO386</code> (for <code>386</code> only, default is auto-detected <li><code>$GO386</code> (for <code>386</code> only, default is auto-detected
if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise) if built on either <code>386</code> or <code>amd64</code>, <code>387</code> otherwise)
@ -609,9 +614,10 @@ This controls the code generated by gc to use either the 387 floating-point unit
floating point computations. floating point computations.
</p> </p>
<ul> <ul>
<li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later). <li><code>GO386=387</code>: use x87 for floating point operations; should support all x86 chips (Pentium MMX or later).</li>
<li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later. <li><code>GO386=sse2</code>: use SSE2 for floating point operations; has better performance than 387, but only available on Pentium 4/Opteron/Athlon 64 or later.</li>
</ul> </ul>
</li>
<li><code>$GOARM</code> (for <code>arm</code> only; default is auto-detected if building <li><code>$GOARM</code> (for <code>arm</code> only; default is auto-detected if building
on the target processor, 6 if not) on the target processor, 6 if not)
@ -620,9 +626,9 @@ This sets the ARM floating point co-processor architecture version the run-time
should target. If you are compiling on the target system, its value will be auto-detected. should target. If you are compiling on the target system, its value will be auto-detected.
</p> </p>
<ul> <ul>
<li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor <li><code>GOARM=5</code>: use software floating point; when CPU doesn't have VFP co-processor</li>
<li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported) <li><code>GOARM=6</code>: use VFPv1 only; default if cross compiling; usually ARM11 or better cores (VFPv2 or better is also supported)</li>
<li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores <li><code>GOARM=7</code>: use VFPv3; usually Cortex-A cores</li>
</ul> </ul>
<p> <p>
If in doubt, leave this variable unset, and adjust it if required If in doubt, leave this variable unset, and adjust it if required
@ -631,6 +637,17 @@ The <a href="//golang.org/wiki/GoArm">GoARM</a> page
on the <a href="//golang.org/wiki">Go community wiki</a> on the <a href="//golang.org/wiki">Go community wiki</a>
contains further details regarding Go's ARM support. contains further details regarding Go's ARM support.
</p> </p>
</li>
<li><code>$GOMIPS</code> (for <code>mips</code> and <code>mipsle</code> only)
<p>
This sets whether to use floating point instructions.
</p>
<ul>
<li><code>GOMIPS=hardfloat</code>: use floating point instructions (the default)</li>
<li><code>GOMIPS=softfloat</code>: use soft floating point</li>
</ul>
</li>
</ul> </ul>

View file

@ -8,14 +8,14 @@
<h2 id="download">Download the Go distribution</h2> <h2 id="download">Download the Go distribution</h2>
<p> <p>
<a href="https://golang.org/dl/" id="start" class="download"> <a href="/dl/" id="start" class="download">
<span class="big">Download Go</span> <span class="big">Download Go</span>
<span class="desc">Click here to visit the downloads page</span> <span class="desc">Click here to visit the downloads page</span>
</a> </a>
</p> </p>
<p> <p>
<a href="https://golang.org/dl/" target="_blank">Official binary <a href="/dl/" target="_blank">Official binary
distributions</a> are available for the FreeBSD (release 10-STABLE and above), distributions</a> are available for the FreeBSD (release 10-STABLE and above),
Linux, Mac OS X (10.8 and above), and Windows operating systems and Linux, Mac OS X (10.8 and above), and Windows operating systems and
the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor the 32-bit (<code>386</code>) and 64-bit (<code>amd64</code>) x86 processor
@ -33,7 +33,7 @@ system and architecture, try
<h2 id="requirements">System requirements</h2> <h2 id="requirements">System requirements</h2>
<p> <p>
Go <a href="https://golang.org/dl/">binary distributions</a> are available for these supported operating systems and architectures. Go <a href="/dl/">binary distributions</a> are available for these supported operating systems and architectures.
Please ensure your system meets these requirements before proceeding. Please ensure your system meets these requirements before proceeding.
If your OS or architecture is not on the list, you may be able to If your OS or architecture is not on the list, you may be able to
<a href="/doc/install/source">install from source</a> or <a href="/doc/install/source">install from source</a> or
@ -77,7 +77,7 @@ first <a href="#uninstall">remove the existing version</a>.
<h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3> <h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
<p> <p>
<a href="https://golang.org/dl/">Download the archive</a> <a href="/dl/">Download the archive</a>
and extract it into <code>/usr/local</code>, creating a Go tree in and extract it into <code>/usr/local</code>, creating a Go tree in
<code>/usr/local/go</code>. For example: <code>/usr/local/go</code>. For example:
</p> </p>
@ -106,6 +106,14 @@ variable. You can do this by adding this line to your <code>/etc/profile</code>
export PATH=$PATH:/usr/local/go/bin export PATH=$PATH:/usr/local/go/bin
</pre> </pre>
<p>
<b>Note</b>: changes made to a <code>profile</code> file may not apply until the
next time you log into your computer.
To apply the changes immediately, just run the shell commands directly
or execute them from the profile using a command such as
<code>source $HOME/.profile</code>.
</p>
<h4 id="tarball_non_standard">Installing to a custom location</h4> <h4 id="tarball_non_standard">Installing to a custom location</h4>
<p> <p>
@ -138,7 +146,7 @@ location.
<h3 id="osx">Mac OS X package installer</h3> <h3 id="osx">Mac OS X package installer</h3>
<p> <p>
<a href="https://golang.org/dl/">Download the package file</a>, <a href="/dl/">Download the package file</a>,
open it, and follow the prompts to install the Go tools. open it, and follow the prompts to install the Go tools.
The package installs the Go distribution to <code>/usr/local/go</code>. The package installs the Go distribution to <code>/usr/local/go</code>.
</p> </p>
@ -167,7 +175,7 @@ MSI installer that configures your installation automatically.
<h4 id="windows_msi">MSI installer</h4> <h4 id="windows_msi">MSI installer</h4>
<p> <p>
Open the <a href="https://golang.org/dl/">MSI file</a> Open the <a href="/dl/">MSI file</a>
and follow the prompts to install the Go tools. and follow the prompts to install the Go tools.
By default, the installer puts the Go distribution in <code>c:\Go</code>. By default, the installer puts the Go distribution in <code>c:\Go</code>.
</p> </p>
@ -185,7 +193,7 @@ command prompts for the change to take effect.
<h4 id="windows_zip">Zip archive</h4> <h4 id="windows_zip">Zip archive</h4>
<p> <p>
<a href="https://golang.org/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>). <a href="/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
</p> </p>
<p> <p>
@ -278,7 +286,7 @@ If you see the "hello, world" message then your Go installation is working.
<p> <p>
You can run <code>go</code> <code>install</code> to install the binary into You can run <code>go</code> <code>install</code> to install the binary into
your workspace's <code>bin</code> directory your workspace's <code>bin</code> directory
or <code>go</code> <code>clean</code> to remove it. or <code>go</code> <code>clean</code> <code>-i</code> to remove it.
</p> </p>
<p> <p>

View file

@ -20,11 +20,11 @@ func viewRecord(w http.ResponseWriter, r *http.Request) {
key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil) key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
record := new(Record) record := new(Record)
if err := datastore.Get(c, key, record); err != nil { if err := datastore.Get(c, key, record); err != nil {
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
if err := viewTemplate.Execute(w, record); err != nil { if err := viewTemplate.Execute(w, record); err != nil {
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }

View file

@ -33,7 +33,7 @@ type appHandler func(http.ResponseWriter, *http.Request) error
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if err := fn(w, r); err != nil { if err := fn(w, r); err != nil {
http.Error(w, err.Error(), 500) http.Error(w, err.Error(), http.StatusInternalServerError)
} }
} }

View file

@ -58,7 +58,7 @@ simple, reliable, and efficient software.
<div id="gopher"></div> <div id="gopher"></div>
<a href="https://golang.org/dl/" id="start"> <a href="/dl/" id="start">
<span class="big">Download Go</span> <span class="big">Download Go</span>
<span class="desc"> <span class="desc">
Binary distributions available for<br> Binary distributions available for<br>
@ -74,7 +74,7 @@ Linux, Mac OS X, Windows, and more.
<div class="left"> <div class="left">
<div id="video"> <div id="video">
<div class="rootHeading">Featured video</div> <div class="rootHeading">Featured video</div>
<iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe> <div class="js-frontpage-video" style="--aspect-ratio-padding: 58.07%;"><iframe width="415" height="241" src="//www.youtube.com/embed/ytEkHepK08c" frameborder="0" allowfullscreen></iframe></div>
</div> </div>
</div> </div>
@ -153,6 +153,10 @@ Linux, Mac OS X, Windows, and more.
]; ];
var v = videos[Math.floor(Math.random()*videos.length)]; var v = videos[Math.floor(Math.random()*videos.length)];
$('#video iframe').attr('height', v.h).attr('src', v.s); $('#video iframe').attr('height', v.h).attr('src', v.s);
// Compute the aspect ratio (as a percentage) of the video
// using the fixed width 415 and the height of the current video, v.h.
var ar = 100*v.h/415;
$('.js-frontpage-video').attr('style', '--aspect-ratio-padding: ' + ar + '%;');
}); });
{{end}} {{end}}

View file

@ -3,7 +3,7 @@ the code and data maintained as part of the IANA Time Zone Database.
The IANA asserts that the database is in the public domain. The IANA asserts that the database is in the public domain.
For more information, see For more information, see
http://www.iana.org/time-zones https://www.iana.org/time-zones
ftp://ftp.iana.org/tz/code/tz-link.htm ftp://ftp.iana.org/tz/code/tz-link.htm
http://tools.ietf.org/html/rfc6557 http://tools.ietf.org/html/rfc6557

View file

@ -5,7 +5,7 @@
# This script rebuilds the time zone files using files # This script rebuilds the time zone files using files
# downloaded from the ICANN/IANA distribution. # downloaded from the ICANN/IANA distribution.
# Consult http://www.iana.org/time-zones for the latest versions. # Consult https://www.iana.org/time-zones for the latest versions.
# Versions to use. # Versions to use.
CODE=2017c CODE=2017c
@ -16,8 +16,8 @@ rm -rf work
mkdir work mkdir work
cd work cd work
mkdir zoneinfo mkdir zoneinfo
curl -O http://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz curl -L -O https://www.iana.org/time-zones/repository/releases/tzcode$CODE.tar.gz
curl -O http://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz curl -L -O https://www.iana.org/time-zones/repository/releases/tzdata$DATA.tar.gz
tar xzf tzcode$CODE.tar.gz tar xzf tzcode$CODE.tar.gz
tar xzf tzdata$DATA.tar.gz tar xzf tzdata$DATA.tar.gz
@ -48,4 +48,3 @@ else
rm -rf work rm -rf work
fi fi
echo New time zone files in zoneinfo.zip. echo New time zone files in zoneinfo.zip.

View file

@ -8,4 +8,17 @@ mobile subrepository:
To run the standard library tests, see androidtest.bash. Run it as To run the standard library tests, see androidtest.bash. Run it as
CC_FOR_TARGET=.../ndk-gcc GOARCH=arm GOARM=7 ./androidtest.bash CC_FOR_TARGET=$STANDALONE_NDK_PATH/bin/clang GOARCH=arm64 ./androidtest.bash
To create a standalone android NDK tool chain, follow the instructions on
https://developer.android.com/ndk/guides/standalone_toolchain
To run tests on the Android device, add the bin directory to PATH so the
go tool can find the go_android_$GOARCH_exec wrapper generated by
androidtest.bash. Then, use the same GOARCH as when androidtest.bash ran
and set GOOS to android. For example, to run the go1 benchmarks
export PATH=$GOROOT/bin:$PATH
cd $GOROOT/test/bench/go1/
GOOS=android GOARCH=arm64 go test -bench=. -count=N -timeout=T

View file

@ -21,6 +21,9 @@ import (
) )
func run(args ...string) string { func run(args ...string) string {
if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
args = append(strings.Split(flags, " "), args...)
}
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
cmd := exec.Command("adb", args...) cmd := exec.Command("adb", args...)
cmd.Stdout = io.MultiWriter(os.Stdout, buf) cmd.Stdout = io.MultiWriter(os.Stdout, buf)

View file

@ -349,6 +349,14 @@ var ptrTests = []ptrTest{
body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`, body: `var wg sync.WaitGroup; wg.Add(100); for i := 0; i < 100; i++ { go func(i int) { for j := 0; j < 100; j++ { C.f(); runtime.GOMAXPROCS(i) }; wg.Done() }(i) }; wg.Wait()`,
fail: false, fail: false,
}, },
{
// Test poller deadline with cgocheck=2. Issue #23435.
name: "deadline",
c: `#define US 10`,
imports: []string{"os", "time"},
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
fail: false,
},
} }
func TestPointerChecks(t *testing.T) { func TestPointerChecks(t *testing.T) {

View file

@ -5,7 +5,7 @@
package main package main
/* /*
#cgo LDFLAGS: -c #cgo LDFLAGS: -L/nonexist
void test() { void test() {
xxx; // ERROR HERE xxx; // ERROR HERE

View file

@ -31,6 +31,8 @@ struct S {
int x; int x;
}; };
const char *cstr = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter); extern enum E myConstFunc(struct S* const ctx, int const id, struct S **const filter);
enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; } enum E myConstFunc(struct S *const ctx, int const id, struct S **const filter) { return 0; }
@ -149,6 +151,18 @@ func benchCgoCall(b *testing.B) {
} }
} }
var sinkString string
func benchGoString(b *testing.B) {
for i := 0; i < b.N; i++ {
sinkString = C.GoString(C.cstr)
}
const want = "abcefghijklmnopqrstuvwxyzABCEFGHIJKLMNOPQRSTUVWXYZ1234567890"
if sinkString != want {
b.Fatalf("%q != %q", sinkString, want)
}
}
// Issue 2470. // Issue 2470.
func testUnsignedInt(t *testing.T) { func testUnsignedInt(t *testing.T) {
a := (int64)(C.UINT32VAL) a := (int64)(C.UINT32VAL)

View file

@ -27,6 +27,7 @@ func testBuildID(t *testing.T) {
defer f.Close() defer f.Close()
c := 0 c := 0
sections:
for i, s := range f.Sections { for i, s := range f.Sections {
if s.Type != elf.SHT_NOTE { if s.Type != elf.SHT_NOTE {
continue continue
@ -47,7 +48,7 @@ func testBuildID(t *testing.T) {
if len(d) < 12 { if len(d) < 12 {
t.Logf("note section %d too short (%d < 12)", i, len(d)) t.Logf("note section %d too short (%d < 12)", i, len(d))
continue continue sections
} }
namesz := f.ByteOrder.Uint32(d) namesz := f.ByteOrder.Uint32(d)
@ -59,7 +60,7 @@ func testBuildID(t *testing.T) {
if int(12+an+ad) > len(d) { if int(12+an+ad) > len(d) {
t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz) t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
continue continue sections
} }
// 3 == NT_GNU_BUILD_ID // 3 == NT_GNU_BUILD_ID

View file

@ -86,5 +86,9 @@ func Test21809(t *testing.T) { test21809(t) }
func Test6907(t *testing.T) { test6907(t) } func Test6907(t *testing.T) { test6907(t) }
func Test6907Go(t *testing.T) { test6907Go(t) } func Test6907Go(t *testing.T) { test6907Go(t) }
func Test21897(t *testing.T) { test21897(t) } func Test21897(t *testing.T) { test21897(t) }
func Test22906(t *testing.T) { test22906(t) }
func Test24206(t *testing.T) { test24206(t) }
func Test25143(t *testing.T) { test25143(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) } func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }

View file

@ -1,16 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Issue 19832. Functions taking a pointer typedef were being expanded and triggering a compiler error.
package cgotest
// typedef struct { int i; } *PS;
// void T19832(PS p) {}
import "C"
import "testing"
func test19832(t *testing.T) {
C.T19832(nil)
}

View file

@ -0,0 +1,54 @@
// +build amd64,linux
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgotest
// Test that C.GoString uses IndexByte in safe manner.
/*
#include <sys/mman.h>
// Returns string with null byte at the last valid address
char* dangerousString1() {
int pageSize = 4096;
char *data = mmap(0, 2 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
mprotect(data + pageSize,pageSize,PROT_NONE);
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
int i = start;
for (; i < pageSize; i++) {
data[i] = 'x';
}
data[pageSize -1 ] = 0;
return data+start;
}
char* dangerousString2() {
int pageSize = 4096;
char *data = mmap(0, 3 * pageSize, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
mprotect(data + 2 * pageSize,pageSize,PROT_NONE);
int start = pageSize - 123 - 1; // last 123 bytes of first page + 1 null byte
int i = start;
for (; i < 2 * pageSize; i++) {
data[i] = 'x';
}
data[2*pageSize -1 ] = 0;
return data+start;
}
*/
import "C"
import (
"testing"
)
func test24206(t *testing.T) {
if l := len(C.GoString(C.dangerousString1())); l != 123 {
t.Errorf("Incorrect string length - got %d, want 123", l)
}
if l := len(C.GoString(C.dangerousString2())); l != 4096+123 {
t.Errorf("Incorrect string length - got %d, want %d", l, 4096+123)
}
}

View file

@ -0,0 +1,13 @@
// +build !amd64 !linux
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgotest
import "testing"
func test24206(t *testing.T) {
t.Skip("Skipping on non-amd64 or non-linux system")
}

View file

@ -0,0 +1,22 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cgotest
import "C"
import "testing"
func issue25143sum(ns ...C.int) C.int {
total := C.int(0)
for _, n := range ns {
total += n
}
return total
}
func test25143(t *testing.T) {
if got, want := issue25143sum(1, 2, 3), C.int(6); got != want {
t.Errorf("issue25143sum(1, 2, 3) == %v, expected %v", got, want)
}
}

View file

@ -4,6 +4,25 @@
// +build !windows // +build !windows
#include <stdint.h>
#include <dlfcn.h>
// Write our own versions of dlopen/dlsym/dlclose so that we represent
// the opaque handle as a Go uintptr rather than a Go pointer to avoid
// garbage collector confusion. See issue 23663.
uintptr_t dlopen4029(char* name, int flags) {
return (uintptr_t)(dlopen(name, flags));
}
uintptr_t dlsym4029(uintptr_t handle, char* name) {
return (uintptr_t)(dlsym((void*)(handle), name));
}
int dlclose4029(uintptr_t handle) {
return dlclose((void*)(handle));
}
void call4029(void *arg) { void call4029(void *arg) {
void (*fn)(void) = arg; void (*fn)(void) = arg;
fn(); fn();

View file

@ -7,10 +7,15 @@
package cgotest package cgotest
/* /*
#include <stdint.h>
#include <dlfcn.h> #include <dlfcn.h>
#cgo linux LDFLAGS: -ldl #cgo linux LDFLAGS: -ldl
extern void call4029(void *arg); extern uintptr_t dlopen4029(char*, int);
extern uintptr_t dlsym4029(uintptr_t, char*);
extern int dlclose4029(uintptr_t);
extern void call4029(uintptr_t arg);
*/ */
import "C" import "C"
@ -51,15 +56,15 @@ func test4029(t *testing.T) {
} }
func loadThySelf(t *testing.T, symbol string) { func loadThySelf(t *testing.T, symbol string) {
this_process := C.dlopen(nil, C.RTLD_NOW) this_process := C.dlopen4029(nil, C.RTLD_NOW)
if this_process == nil { if this_process == 0 {
t.Error("dlopen:", C.GoString(C.dlerror())) t.Error("dlopen:", C.GoString(C.dlerror()))
return return
} }
defer C.dlclose(this_process) defer C.dlclose4029(this_process)
symbol_address := C.dlsym(this_process, C.CString(symbol)) symbol_address := C.dlsym4029(this_process, C.CString(symbol))
if symbol_address == nil { if symbol_address == 0 {
t.Error("dlsym:", C.GoString(C.dlerror())) t.Error("dlsym:", C.GoString(C.dlerror()))
return return
} }

View file

@ -9,7 +9,7 @@
TEXT cas<>(SB),NOSPLIT,$0 TEXT cas<>(SB),NOSPLIT,$0
MOVW $0xffff0fc0, R15 // R15 is PC MOVW $0xffff0fc0, R15 // R15 is PC
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0 TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
// Save link register // Save link register
MOVW R14, R4 MOVW R14, R4

View file

@ -6,7 +6,7 @@
#include "textflag.h" #include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-8-0 TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
// Save link register // Save link register
MOVD R30, R9 MOVD R30, R9

View file

@ -7,7 +7,7 @@
#include "textflag.h" #include "textflag.h"
TEXT ·RewindAndSetgid(SB),NOSPLIT,$-4-0 TEXT ·RewindAndSetgid(SB),NOSPLIT|NOFRAME,$0-0
// Rewind stack pointer so anything that happens on the stack // Rewind stack pointer so anything that happens on the stack
// will clobber the test pattern created by the caller // will clobber the test pattern created by the caller
ADDU $(1024*8), R29 ADDU $(1024*8), R29

View file

@ -32,7 +32,7 @@ func IntoGoAndBack() {
func testSigprocmask(t *testing.T) { func testSigprocmask(t *testing.T) {
if r := C.RunSigThread(); r != 0 { if r := C.RunSigThread(); r != 0 {
t.Error("pthread_create/pthread_join failed") t.Errorf("pthread_create/pthread_join failed: %d", r)
} }
if !blocked { if !blocked {
t.Error("Go runtime unblocked SIGIO") t.Error("Go runtime unblocked SIGIO")

View file

@ -0,0 +1,74 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build cgo
package cgotest
/*
// It's going to be hard to include a whole real JVM to test this.
// So we'll simulate a really easy JVM using just the parts we need.
// This is the relevant part of jni.h.
struct _jobject;
typedef struct _jobject *jobject;
typedef jobject jclass;
typedef jobject jthrowable;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jarray jobjectArray;
typedef jobject jweak;
// Note: jvalue is already a non-pointer type due to it being a C union.
*/
import "C"
import (
"testing"
)
func test22906(t *testing.T) {
var x1 C.jobject = 0 // Note: 0, not nil. That makes sure we use uintptr for these types.
_ = x1
var x2 C.jclass = 0
_ = x2
var x3 C.jthrowable = 0
_ = x3
var x4 C.jstring = 0
_ = x4
var x5 C.jarray = 0
_ = x5
var x6 C.jbooleanArray = 0
_ = x6
var x7 C.jbyteArray = 0
_ = x7
var x8 C.jcharArray = 0
_ = x8
var x9 C.jshortArray = 0
_ = x9
var x10 C.jintArray = 0
_ = x10
var x11 C.jlongArray = 0
_ = x11
var x12 C.jfloatArray = 0
_ = x12
var x13 C.jdoubleArray = 0
_ = x13
var x14 C.jobjectArray = 0
_ = x14
var x15 C.jweak = 0
_ = x15
}

View file

@ -13,6 +13,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp"
"strings" "strings"
"syscall" "syscall"
"testing" "testing"
@ -166,6 +167,28 @@ func testInstall(t *testing.T, exe, libgoa, libgoh string, buildcmd ...string) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, libgoh)
}
var badLineRegexp = regexp.MustCompile(`(?m)^#line [0-9]+ "/.*$`)
// checkLineComments checks that the export header generated by
// -buildmode=c-archive doesn't have any absolute paths in the #line
// comments. We don't want those paths because they are unhelpful for
// the user and make the files change based on details of the location
// of GOPATH.
func checkLineComments(t *testing.T, hdrname string) {
hdr, err := ioutil.ReadFile(hdrname)
if err != nil {
if !os.IsNotExist(err) {
t.Error(err)
}
return
}
if line := badLineRegexp.Find(hdr); line != nil {
t.Errorf("bad #line directive with absolute path in %s: %q", hdrname, line)
}
} }
func TestInstall(t *testing.T) { func TestInstall(t *testing.T) {
@ -209,6 +232,7 @@ func TestEarlySignalHandler(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a") ccArgs := append(cc, "-o", "testp"+exeSuffix, "main2.c", "libgo2.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -238,6 +262,7 @@ func TestSignalForwarding(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a") ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -260,6 +285,9 @@ func TestSignalForwarding(t *testing.T) {
} }
func TestSignalForwardingExternal(t *testing.T) { func TestSignalForwardingExternal(t *testing.T) {
if GOOS == "freebsd" {
t.Skipf("skipping on %s/%s; signal always goes to the Go runtime", GOOS, GOARCH)
}
checkSignalForwardingTest(t) checkSignalForwardingTest(t)
defer func() { defer func() {
@ -275,6 +303,7 @@ func TestSignalForwardingExternal(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo2.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a") ccArgs := append(cc, "-o", "testp"+exeSuffix, "main5.c", "libgo2.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -387,6 +416,7 @@ func TestOsSignal(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo3.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a") ccArgs := append(cc, "-o", "testp"+exeSuffix, "main3.c", "libgo3.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -419,6 +449,7 @@ func TestSigaltstack(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo4.h")
ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a") ccArgs := append(cc, "-o", "testp"+exeSuffix, "main4.c", "libgo4.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -433,7 +464,7 @@ func TestSigaltstack(t *testing.T) {
} }
const testar = `#!/usr/bin/env bash const testar = `#!/usr/bin/env bash
while expr $1 : '[-]' >/dev/null; do while [[ $1 == -* ]] >/dev/null; do
shift shift
done done
echo "testar" > $1 echo "testar" > $1
@ -470,6 +501,7 @@ func TestExtar(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo4.h")
if _, err := os.Stat("testar.ran"); err != nil { if _, err := os.Stat("testar.ran"); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -570,6 +602,7 @@ func TestSIGPROF(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo6.h")
ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a") ccArgs := append(cc, "-o", "testp6"+exeSuffix, "main6.c", "libgo6.a")
if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil { if out, err := exec.Command(ccArgs[0], ccArgs[1:]...).CombinedOutput(); err != nil {
@ -608,6 +641,7 @@ func TestCompileWithoutShared(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
checkLineComments(t, "libgo2.h")
exe := "./testnoshared" + exeSuffix exe := "./testnoshared" + exeSuffix
@ -642,3 +676,50 @@ func TestCompileWithoutShared(t *testing.T) {
t.Logf("%s", out) t.Logf("%s", out)
expectSignal(t, err, syscall.SIGPIPE) expectSignal(t, err, syscall.SIGPIPE)
} }
// Test that installing a second time recreates the header files.
func TestCachedInstall(t *testing.T) {
defer os.RemoveAll("pkg")
h1 := filepath.Join("pkg", libgodir, "libgo.h")
h2 := filepath.Join("pkg", libgodir, "p.h")
buildcmd := []string{"go", "install", "-i", "-buildmode=c-archive", "libgo"}
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
if _, err := os.Stat(h1); err != nil {
t.Errorf("libgo.h not installed: %v", err)
}
if _, err := os.Stat(h2); err != nil {
t.Errorf("p.h not installed: %v", err)
}
if err := os.Remove(h1); err != nil {
t.Fatal(err)
}
if err := os.Remove(h2); err != nil {
t.Fatal(err)
}
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = gopathEnv
t.Log(buildcmd)
if out, err := cmd.CombinedOutput(); err != nil {
t.Logf("%s", out)
t.Fatal(err)
}
if _, err := os.Stat(h1); err != nil {
t.Errorf("libgo.h not installed in second run: %v", err)
}
if _, err := os.Stat(h2); err != nil {
t.Errorf("p.h not installed in second run: %v", err)
}
}

View file

@ -85,6 +85,8 @@ int main(int argc, char** argv) {
printf("write(2) unexpectedly succeeded\n"); printf("write(2) unexpectedly succeeded\n");
return 0; return 0;
} }
printf("did not receieve SIGPIPE\n");
return 0;
} }
default: default:
printf("Unknown test: %d\n", test); printf("Unknown test: %d\n", test);

View file

@ -7,6 +7,7 @@ package cshared_test
import ( import (
"debug/elf" "debug/elf"
"fmt" "fmt"
"io/ioutil"
"log" "log"
"os" "os"
"os/exec" "os/exec"
@ -55,7 +56,8 @@ func TestMain(m *testing.M) {
androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid()) androiddir = fmt.Sprintf("/data/local/tmp/testcshared-%d", os.Getpid())
if GOOS == "android" { if GOOS == "android" {
cmd := exec.Command("adb", "shell", "mkdir", "-p", androiddir) args := append(adbCmd(), "shell", "mkdir", "-p", androiddir)
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Fatalf("setupAndroid failed: %v\n%s\n", err, out) log.Fatalf("setupAndroid failed: %v\n%s\n", err, out)
@ -154,11 +156,19 @@ func cmdToRun(name string) string {
return "./" + name + exeSuffix return "./" + name + exeSuffix
} }
func adbCmd() []string {
cmd := []string{"adb"}
if flags := os.Getenv("GOANDROID_ADB_FLAGS"); flags != "" {
cmd = append(cmd, strings.Split(flags, " ")...)
}
return cmd
}
func adbPush(t *testing.T, filename string) { func adbPush(t *testing.T, filename string) {
if GOOS != "android" { if GOOS != "android" {
return return
} }
args := []string{"adb", "push", filename, fmt.Sprintf("%s/%s", androiddir, filename)} args := append(adbCmd(), "push", filename, fmt.Sprintf("%s/%s", androiddir, filename))
cmd := exec.Command(args[0], args[1:]...) cmd := exec.Command(args[0], args[1:]...)
if out, err := cmd.CombinedOutput(); err != nil { if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("adb command failed: %v\n%s\n", err, out) t.Fatalf("adb command failed: %v\n%s\n", err, out)
@ -169,7 +179,7 @@ func adbRun(t *testing.T, env []string, adbargs ...string) string {
if GOOS != "android" { if GOOS != "android" {
t.Fatalf("trying to run adb command when operating system is not android.") t.Fatalf("trying to run adb command when operating system is not android.")
} }
args := []string{"adb", "shell"} args := append(adbCmd(), "shell")
// Propagate LD_LIBRARY_PATH to the adb shell invocation. // Propagate LD_LIBRARY_PATH to the adb shell invocation.
for _, e := range env { for _, e := range env {
if strings.Index(e, "LD_LIBRARY_PATH=") != -1 { if strings.Index(e, "LD_LIBRARY_PATH=") != -1 {
@ -237,7 +247,7 @@ func createHeaders() error {
} }
if GOOS == "android" { if GOOS == "android" {
args = []string{"adb", "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname)} args = append(adbCmd(), "push", libgoname, fmt.Sprintf("%s/%s", androiddir, libgoname))
cmd = exec.Command(args[0], args[1:]...) cmd = exec.Command(args[0], args[1:]...)
out, err = cmd.CombinedOutput() out, err = cmd.CombinedOutput()
if err != nil { if err != nil {
@ -270,7 +280,8 @@ func cleanupAndroid() {
if GOOS != "android" { if GOOS != "android" {
return return
} }
cmd := exec.Command("adb", "shell", "rm", "-rf", androiddir) args := append(adbCmd(), "shell", "rm", "-rf", androiddir)
cmd := exec.Command(args[0], args[1:]...)
out, err := cmd.CombinedOutput() out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out) log.Fatalf("cleanupAndroid failed: %v\n%s\n", err, out)
@ -311,7 +322,11 @@ func TestExportedSymbolsWithDynamicLoad(t *testing.T) {
createHeadersOnce(t) createHeadersOnce(t)
if GOOS != "freebsd" {
runCC(t, "-o", cmd, "main1.c", "-ldl") runCC(t, "-o", cmd, "main1.c", "-ldl")
} else {
runCC(t, "-o", cmd, "main1.c")
}
adbPush(t, cmd) adbPush(t, cmd)
defer os.Remove(bin) defer os.Remove(bin)
@ -400,7 +415,11 @@ func testSignalHandlers(t *testing.T, pkgname, cfile, cmd string) {
"-o", libname, pkgname, "-o", libname, pkgname,
) )
adbPush(t, libname) adbPush(t, libname)
if GOOS != "freebsd" {
runCC(t, "-pthread", "-o", cmd, cfile, "-ldl") runCC(t, "-pthread", "-o", cmd, cfile, "-ldl")
} else {
runCC(t, "-pthread", "-o", cmd, cfile)
}
adbPush(t, cmd) adbPush(t, cmd)
bin := cmdToRun(cmd) bin := cmdToRun(cmd)
@ -477,3 +496,99 @@ func TestPIE(t *testing.T) {
} }
} }
} }
// Test that installing a second time recreates the header files.
func TestCachedInstall(t *testing.T) {
tmpdir, err := ioutil.TempDir("", "cshared")
if err != nil {
t.Fatal(err)
}
// defer os.RemoveAll(tmpdir)
copyFile(t, filepath.Join(tmpdir, "src", "libgo", "libgo.go"), filepath.Join("src", "libgo", "libgo.go"))
copyFile(t, filepath.Join(tmpdir, "src", "p", "p.go"), filepath.Join("src", "p", "p.go"))
env := append(os.Environ(), "GOPATH="+tmpdir)
buildcmd := []string{"go", "install", "-x", "-i", "-buildmode=c-shared", "-installsuffix", "testcshared", "libgo"}
cmd := exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = env
t.Log(buildcmd)
out, err := cmd.CombinedOutput()
t.Logf("%s", out)
if err != nil {
t.Fatal(err)
}
var libgoh, ph string
walker := func(path string, info os.FileInfo, err error) error {
if err != nil {
t.Fatal(err)
}
var ps *string
switch filepath.Base(path) {
case "libgo.h":
ps = &libgoh
case "p.h":
ps = &ph
}
if ps != nil {
if *ps != "" {
t.Fatalf("%s found again", *ps)
}
*ps = path
}
return nil
}
if err := filepath.Walk(tmpdir, walker); err != nil {
t.Fatal(err)
}
if libgoh == "" {
t.Fatal("libgo.h not installed")
}
if ph == "" {
t.Fatal("p.h not installed")
}
if err := os.Remove(libgoh); err != nil {
t.Fatal(err)
}
if err := os.Remove(ph); err != nil {
t.Fatal(err)
}
cmd = exec.Command(buildcmd[0], buildcmd[1:]...)
cmd.Env = env
t.Log(buildcmd)
out, err = cmd.CombinedOutput()
t.Logf("%s", out)
if err != nil {
t.Fatal(err)
}
if _, err := os.Stat(libgoh); err != nil {
t.Errorf("libgo.h not installed in second run: %v", err)
}
if _, err := os.Stat(ph); err != nil {
t.Errorf("p.h not installed in second run: %v", err)
}
}
// copyFile copies src to dst.
func copyFile(t *testing.T, dst, src string) {
t.Helper()
data, err := ioutil.ReadFile(src)
if err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(filepath.Dir(dst), 0777); err != nil {
t.Fatal(err)
}
if err := ioutil.WriteFile(dst, data, 0666); err != nil {
t.Fatal(err)
}
}

View file

@ -9,7 +9,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#define fd (100) #define fd (30)
// Tests libgo2.so, which does not export any functions. // Tests libgo2.so, which does not export any functions.
// Read a string from the file descriptor and print it. // Read a string from the file descriptor and print it.
@ -21,7 +21,7 @@ int main(void) {
// The descriptor will be initialized in a thread, so we have to // The descriptor will be initialized in a thread, so we have to
// give a chance to get opened. // give a chance to get opened.
for (i = 0; i < 1000; i++) { for (i = 0; i < 200; i++) {
n = read(fd, buf, sizeof buf); n = read(fd, buf, sizeof buf);
if (n >= 0) if (n >= 0)
break; break;
@ -33,7 +33,7 @@ int main(void) {
// An EBADF error means that the shared library has not opened the // An EBADF error means that the shared library has not opened the
// descriptor yet. // descriptor yet.
ts.tv_sec = 0; ts.tv_sec = 0;
ts.tv_nsec = 1000000; ts.tv_nsec = 10000000;
nanosleep(&ts, NULL); nanosleep(&ts, NULL);
} }

View file

@ -21,7 +21,7 @@ import (
// that the C code can also use. // that the C code can also use.
const ( const (
fd = 100 fd = 30
) )
func init() { func init() {

View file

@ -0,0 +1,21 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "plugin"
func main() {
p, err := plugin.Open("issue24351.so")
if err != nil {
panic(err)
}
f, err := p.Lookup("B")
if err != nil {
panic(err)
}
c := make(chan bool)
f.(func(chan bool))(c)
<-c
}

View file

@ -0,0 +1,14 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import "fmt"
func B(c chan bool) {
go func() {
fmt.Println(1.5)
c <- true
}()
}

View file

@ -85,3 +85,8 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22175 src/issue22175/main.
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue.22295.so issue22295.pkg
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue22295 src/issue22295.pkg/main.go
./issue22295 ./issue22295
# Test for issue 24351
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o issue24351.so src/issue24351/plugin.go
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -o issue24351 src/issue24351/main.go
./issue24351

View file

@ -407,7 +407,7 @@ func (d *tempDir) RemoveAll(t *testing.T) {
return return
} }
if err := os.RemoveAll(d.base); err != nil { if err := os.RemoveAll(d.base); err != nil {
t.Fatal("Failed to remove temp dir: %v", err) t.Fatalf("Failed to remove temp dir: %v", err)
} }
} }

View file

@ -351,10 +351,10 @@ func readNotes(f *elf.File) ([]*note, error) {
func dynStrings(t *testing.T, path string, flag elf.DynTag) []string { func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
f, err := elf.Open(path) f, err := elf.Open(path)
defer f.Close()
if err != nil { if err != nil {
t.Fatalf("elf.Open(%q) failed: %v", path, err) t.Fatalf("elf.Open(%q) failed: %v", path, err)
} }
defer f.Close()
dynstrings, err := f.DynString(flag) dynstrings, err := f.DynString(flag)
if err != nil { if err != nil {
t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err) t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
@ -598,7 +598,6 @@ func TestThreeGopathShlibs(t *testing.T) {
// If gccgo is not available or not new enough call t.Skip. Otherwise, // If gccgo is not available or not new enough call t.Skip. Otherwise,
// return a build.Context that is set up for gccgo. // return a build.Context that is set up for gccgo.
func prepGccgo(t *testing.T) build.Context { func prepGccgo(t *testing.T) build.Context {
t.Skip("golang.org/issue/22472")
gccgoName := os.Getenv("GCCGO") gccgoName := os.Getenv("GCCGO")
if gccgoName == "" { if gccgoName == "" {
gccgoName = "gccgo" gccgoName = "gccgo"
@ -648,8 +647,6 @@ func TestGoPathShlibGccgo(t *testing.T) {
// library with gccgo, another GOPATH package that depends on the first and an // library with gccgo, another GOPATH package that depends on the first and an
// executable that links the second library. // executable that links the second library.
func TestTwoGopathShlibsGccgo(t *testing.T) { func TestTwoGopathShlibsGccgo(t *testing.T) {
t.Skip("golang.org/issue/22224")
gccgoContext := prepGccgo(t) gccgoContext := prepGccgo(t)
libgoRE := regexp.MustCompile("libgo.so.[0-9]+") libgoRE := regexp.MustCompile("libgo.so.[0-9]+")
@ -793,6 +790,7 @@ func TestRebuilding(t *testing.T) {
// If the .a file is newer than the .so, the .so is rebuilt (but not the .a) // If the .a file is newer than the .so, the .so is rebuilt (but not the .a)
t.Run("newarchive", func(t *testing.T) { t.Run("newarchive", func(t *testing.T) {
resetFileStamps() resetFileStamps()
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase") goCmd(t, "list", "-linkshared", "-f={{.ImportPath}} {{.Stale}} {{.StaleReason}} {{.Target}}", "depBase")
AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a")) AssertNotRebuilt(t, "new .a file before build", filepath.Join(gopathInstallDir, "depBase.a"))
cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a")) cleanup := touch(t, filepath.Join(gopathInstallDir, "depBase.a"))

View file

@ -1,44 +1,50 @@
Go on iOS Go on iOS
========= =========
To build a cross compiling toolchain for iOS on OS X, first modify clangwrap.sh For details on developing Go for iOS on macOS, see the documentation in the mobile
in misc/ios to match your setup. And then run: subrepository:
GOARM=7 CGO_ENABLED=1 GOARCH=arm CC_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh \ https://github.com/golang/mobile
CXX_FOR_TARGET=`pwd`/../misc/ios/clangwrap.sh ./make.bash
To build a program, use the normal go build command: It is necessary to set up the environment before running tests or programs directly on a
device.
CGO_ENABLED=1 GOARCH=arm go build import/path First make sure you have a valid developer certificate and have setup your device properly
to run apps signed by your developer certificate. Then install the libimobiledevice and
ideviceinstaller tools from https://www.libimobiledevice.org/. Use the HEAD versions from
source; the stable versions have bugs that prevents the Go exec wrapper to install and run
apps.
To run a program on an iDevice, first make sure you have a valid developer Second, the Go exec wrapper must be told the developer account signing identity, the team
certificate and have setup your iDevice properly to run apps signed by your id and a provisioned bundle id to use. They're specified with the environment variables
developer certificate. Then install https://github.com/phonegap/ios-deploy. GOIOS_DEV_ID, GOIOS_TEAM_ID and GOIOS_APP_ID. The detect.go program in this directory will
At a first step, you can try building the famous hello world program to run attempt to auto-detect suitable values. Run it as
on your test device.
(The needed files are provided at https://github.com/minux/go-ios-examples.)
# assume your program binary is helloworld.go, build it into the go run detect.go
# example hello.app bundle.
CGO_ENABLED=1 GOARCH=arm go build -o hello.app/hello helloworld.go
# sign the executable using your developer certificate
codesign -f -s "iPhone Developer" --entitlements hello.app/Entitlements.plist hello.app/hello
# run the program inside lldb on iDevice, run `ios-deploy` for more
# command options
ios-deploy --debug --uninstall --bundle hello.app
# Depending on your ios-deploy version, you might need to enter "run"
# into lldb to run your program, and its output will be shown by lldb.
Notes: which will output something similar to
- A dummy hello.app bundle is provided in this directory to help you get started.
- Running the program on an iDevice requires code sign and thus external linking,
if your program uses cgo, then it will automatically use external linking.
However, if your program does not use cgo, please make sure to add
import _ "runtime/cgo"
so that external linking will be used.
Known issues export GOIOS_DEV_ID="iPhone Developer: xxx@yyy.zzz (XXXXXXXX)"
============ export GOIOS_APP_ID=YYYYYYYY.some.bundle.id
- crypto/x509 won't build, I don't yet know how to get system root on iOS. export GOIOS_TEAM_ID=ZZZZZZZZ
- Because I still want to be able to do native build, CGO_ENABLED=1 is not the
default, yet. If you have multiple devices connected, specify the device UDID with the GOIOS_DEVICE_ID
variable. Use `idevice_id -l` to list all available UDIDs.
Finally, to run the standard library tests, run iostest.bash with GOARCH set. For example,
GOARCH=arm64 ./iostest.bash
To use the go tool directly to run programs and tests, put $GOROOT/bin into PATH to ensure
the go_darwin_$GOARCH_exec wrapper is found. For example, to run the archive/tar tests
export PATH=$GOROOT/bin:$PATH
GOARCH=arm64 go test archive/tar
Note that the go_darwin_$GOARCH_exec wrapper uninstalls any existing app identified by
the bundle id before installing a new app. If the uninstalled app is the last app by
the developer identity, the device might also remove the permission to run apps from
that developer, and the exec wrapper will fail to install the new app. To avoid that,
install another app with the same developer identity but with a different bundle id.
That way, the permission to install apps is held on to while the primary app is
uninstalled.

View file

@ -14,6 +14,7 @@ package main
import ( import (
"bytes" "bytes"
"crypto/x509"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -22,12 +23,14 @@ import (
) )
func main() { func main() {
devID := detectDevID() udids := getLines(exec.Command("idevice_id", "-l"))
if len(udids) == 0 {
fail("no udid found; is a device connected?")
}
udid := detectUDID() mps := detectMobileProvisionFiles(udids)
mps := detectMobileProvisionFiles(udid)
if len(mps) == 0 { if len(mps) == 0 {
fail("did not find mobile provision matching device udid %s", udid) fail("did not find mobile provision matching device udids %q", udids)
} }
fmt.Println("Available provisioning profiles below.") fmt.Println("Available provisioning profiles below.")
@ -35,7 +38,6 @@ func main() {
fmt.Println("will be overwritten when running Go programs.") fmt.Println("will be overwritten when running Go programs.")
for _, mp := range mps { for _, mp := range mps {
fmt.Println() fmt.Println()
fmt.Printf("export GOIOS_DEV_ID=%s\n", devID)
f, err := ioutil.TempFile("", "go_ios_detect_") f, err := ioutil.TempFile("", "go_ios_detect_")
check(err) check(err)
fname := f.Name() fname := f.Name()
@ -46,6 +48,12 @@ func main() {
check(err) check(err)
check(f.Close()) check(f.Close())
cert, err := plistExtract(fname, "DeveloperCertificates:0")
check(err)
pcert, err := x509.ParseCertificate(cert)
check(err)
fmt.Printf("export GOIOS_DEV_ID=\"%s\"\n", pcert.Subject.CommonName)
appID, err := plistExtract(fname, "Entitlements:application-identifier") appID, err := plistExtract(fname, "Entitlements:application-identifier")
check(err) check(err)
fmt.Printf("export GOIOS_APP_ID=%s\n", appID) fmt.Printf("export GOIOS_APP_ID=%s\n", appID)
@ -56,39 +64,7 @@ func main() {
} }
} }
func detectDevID() string { func detectMobileProvisionFiles(udids [][]byte) []string {
cmd := exec.Command("security", "find-identity", "-p", "codesigning", "-v")
lines := getLines(cmd)
for _, line := range lines {
if !bytes.Contains(line, []byte("iPhone Developer")) {
continue
}
if bytes.Contains(line, []byte("REVOKED")) {
continue
}
fields := bytes.Fields(line)
return string(fields[1])
}
fail("no code signing identity found")
panic("unreachable")
}
var udidPrefix = []byte("UniqueDeviceID: ")
func detectUDID() []byte {
cmd := exec.Command("ideviceinfo")
lines := getLines(cmd)
for _, line := range lines {
if bytes.HasPrefix(line, udidPrefix) {
return bytes.TrimPrefix(line, udidPrefix)
}
}
fail("udid not found; is the device connected?")
panic("unreachable")
}
func detectMobileProvisionFiles(udid []byte) []string {
cmd := exec.Command("mdfind", "-name", ".mobileprovision") cmd := exec.Command("mdfind", "-name", ".mobileprovision")
lines := getLines(cmd) lines := getLines(cmd)
@ -98,12 +74,18 @@ func detectMobileProvisionFiles(udid []byte) []string {
continue continue
} }
xmlLines := getLines(parseMobileProvision(string(line))) xmlLines := getLines(parseMobileProvision(string(line)))
matches := 0
for _, udid := range udids {
for _, xmlLine := range xmlLines { for _, xmlLine := range xmlLines {
if bytes.Contains(xmlLine, udid) { if bytes.Contains(xmlLine, udid) {
files = append(files, string(line)) matches++
} }
} }
} }
if matches == len(udids) {
files = append(files, string(line))
}
}
return files return files
} }
@ -121,7 +103,12 @@ func plistExtract(fname string, path string) ([]byte, error) {
func getLines(cmd *exec.Cmd) [][]byte { func getLines(cmd *exec.Cmd) [][]byte {
out := output(cmd) out := output(cmd)
return bytes.Split(out, []byte("\n")) lines := bytes.Split(out, []byte("\n"))
// Skip the empty line at the end.
if len(lines[len(lines)-1]) == 0 {
lines = lines[:len(lines)-1]
}
return lines
} }
func output(cmd *exec.Cmd) []byte { func output(cmd *exec.Cmd) []byte {

View file

@ -21,27 +21,26 @@ package main
import ( import (
"bytes" "bytes"
"encoding/xml"
"errors" "errors"
"flag"
"fmt" "fmt"
"go/build" "go/build"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
"net"
"os" "os"
"os/exec" "os/exec"
"os/signal"
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"sync"
"syscall" "syscall"
"time" "time"
) )
const debug = false const debug = false
var errRetry = errors.New("failed to start test harness (retry attempted)")
var tmpdir string var tmpdir string
var ( var (
@ -88,10 +87,28 @@ func main() {
bundleID = parts[1] bundleID = parts[1]
} }
exitCode, err := runMain()
if err != nil {
log.Fatalf("%v\n", err)
}
os.Exit(exitCode)
}
func runMain() (int, error) {
var err error var err error
tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_") tmpdir, err = ioutil.TempDir("", "go_darwin_arm_exec_")
if err != nil { if err != nil {
log.Fatal(err) return 1, err
}
if !debug {
defer os.RemoveAll(tmpdir)
}
appdir := filepath.Join(tmpdir, "gotest.app")
os.RemoveAll(appdir)
if err := assembleApp(appdir, os.Args[1]); err != nil {
return 1, err
} }
// This wrapper uses complicated machinery to run iOS binaries. It // This wrapper uses complicated machinery to run iOS binaries. It
@ -103,33 +120,43 @@ func main() {
lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock") lockName := filepath.Join(os.TempDir(), "go_darwin_arm_exec-"+deviceID+".lock")
lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666) lock, err = os.OpenFile(lockName, os.O_CREATE|os.O_RDONLY, 0666)
if err != nil { if err != nil {
log.Fatal(err) return 1, err
} }
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil { if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX); err != nil {
log.Fatal(err) return 1, err
} }
// Approximately 1 in a 100 binaries fail to start. If it happens,
// try again. These failures happen for several reasons beyond if err := uninstall(bundleID); err != nil {
// our control, but all of them are safe to retry as they happen return 1, err
// before lldb encounters the initial getwd breakpoint. As we
// know the tests haven't started, we are not hiding flaky tests
// with this retry.
for i := 0; i < 5; i++ {
if i > 0 {
fmt.Fprintln(os.Stderr, "start timeout, trying again")
} }
err = run(os.Args[1], os.Args[2:])
if err == nil || err != errRetry { if err := install(appdir); err != nil {
break return 1, err
} }
if err := mountDevImage(); err != nil {
return 1, err
} }
if !debug {
os.RemoveAll(tmpdir) // Kill any hanging debug bridges that might take up port 3222.
} exec.Command("killall", "idevicedebugserverproxy").Run()
closer, err := startDebugBridge()
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "go_darwin_arm_exec: %v\n", err) return 1, err
os.Exit(1)
} }
defer closer()
if err := run(appdir, bundleID, os.Args[2:]); err != nil {
// If the lldb driver completed with an exit code, use that.
if err, ok := err.(*exec.ExitError); ok {
if ws, ok := err.Sys().(interface{ ExitStatus() int }); ok {
return ws.ExitStatus(), nil
}
}
return 1, err
}
return 0, nil
} }
func getenv(envvar string) string { func getenv(envvar string) string {
@ -140,9 +167,7 @@ func getenv(envvar string) string {
return s return s
} }
func run(bin string, args []string) (err error) { func assembleApp(appdir, bin string) error {
appdir := filepath.Join(tmpdir, "gotest.app")
os.RemoveAll(appdir)
if err := os.MkdirAll(appdir, 0755); err != nil { if err := os.MkdirAll(appdir, 0755); err != nil {
return err return err
} }
@ -182,285 +207,325 @@ func run(bin string, args []string) (err error) {
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
return fmt.Errorf("codesign: %v", err) return fmt.Errorf("codesign: %v", err)
} }
return nil
}
oldwd, err := os.Getwd() // mountDevImage ensures a developer image is mounted on the device.
// The image contains the device lldb server for idevicedebugserverproxy
// to connect to.
func mountDevImage() error {
// Check for existing mount.
cmd := idevCmd(exec.Command("ideviceimagemounter", "-l", "-x"))
out, err := cmd.CombinedOutput()
if err != nil { if err != nil {
return err os.Stderr.Write(out)
return fmt.Errorf("ideviceimagemounter: %v", err)
} }
if err := os.Chdir(filepath.Join(appdir, "..")); err != nil { var info struct {
return err Dict struct {
Data []byte `xml:",innerxml"`
} `xml:"dict"`
} }
defer os.Chdir(oldwd) if err := xml.Unmarshal(out, &info); err != nil {
return fmt.Errorf("mountDevImage: failed to decode mount information: %v", err)
// Setting up lldb is flaky. The test binary itself runs when
// started is set to true. Everything before that is considered
// part of the setup and is retried.
started := false
defer func() {
if r := recover(); r != nil {
if w, ok := r.(waitPanic); ok {
err = w.err
if !started {
fmt.Printf("lldb setup error: %v\n", err)
err = errRetry
} }
return dict, err := parsePlistDict(info.Dict.Data)
}
panic(r)
}
}()
defer exec.Command("killall", "ios-deploy").Run() // cleanup
exec.Command("killall", "ios-deploy").Run()
var opts options
opts, args = parseArgs(args)
// ios-deploy invokes lldb to give us a shell session with the app.
s, err := newSession(appdir, args, opts)
if err != nil { if err != nil {
return err return fmt.Errorf("mountDevImage: failed to parse mount information: %v", err)
}
defer func() {
b := s.out.Bytes()
if err == nil && !debug {
i := bytes.Index(b, []byte("(lldb) process continue"))
if i > 0 {
b = b[i:]
}
}
os.Stdout.Write(b)
}()
cond := func(out *buf) bool {
i0 := s.out.LastIndex([]byte("(lldb)"))
i1 := s.out.LastIndex([]byte("fruitstrap"))
i2 := s.out.LastIndex([]byte(" connect"))
return i0 > 0 && i1 > 0 && i2 > 0
}
if err := s.wait("lldb start", cond, 15*time.Second); err != nil {
panic(waitPanic{err})
}
// Script LLDB. Oh dear.
s.do(`process handle SIGHUP --stop false --pass true --notify false`)
s.do(`process handle SIGPIPE --stop false --pass true --notify false`)
s.do(`process handle SIGUSR1 --stop false --pass true --notify false`)
s.do(`process handle SIGCONT --stop false --pass true --notify false`)
s.do(`process handle SIGSEGV --stop false --pass true --notify false`) // does not work
s.do(`process handle SIGBUS --stop false --pass true --notify false`) // does not work
if opts.lldb {
_, err := io.Copy(s.in, os.Stdin)
if err != io.EOF {
return err
} }
if dict["ImagePresent"] == "true" && dict["Status"] == "Complete" {
return nil return nil
} }
// Some devices only give us an ImageSignature key.
started = true if _, exists := dict["ImageSignature"]; exists {
s.doCmd("run", "stop reason = signal SIGINT", 20*time.Second)
startTestsLen := s.out.Len()
fmt.Fprintln(s.in, `process continue`)
passed := func(out *buf) bool {
// Just to make things fun, lldb sometimes translates \n into \r\n.
return s.out.LastIndex([]byte("\nPASS\n")) > startTestsLen ||
s.out.LastIndex([]byte("\nPASS\r")) > startTestsLen ||
s.out.LastIndex([]byte("\n(lldb) PASS\n")) > startTestsLen ||
s.out.LastIndex([]byte("\n(lldb) PASS\r")) > startTestsLen ||
s.out.LastIndex([]byte("exited with status = 0 (0x00000000) \n")) > startTestsLen ||
s.out.LastIndex([]byte("exited with status = 0 (0x00000000) \r")) > startTestsLen
}
err = s.wait("test completion", passed, opts.timeout)
if passed(s.out) {
// The returned lldb error code is usually non-zero.
// We check for test success by scanning for the final
// PASS returned by the test harness, assuming the worst
// in its absence.
return nil return nil
} }
// No image is mounted. Find a suitable image.
imgPath, err := findDevImage()
if err != nil {
return err return err
}
type lldbSession struct {
cmd *exec.Cmd
in *os.File
out *buf
timedout chan struct{}
exited chan error
}
func newSession(appdir string, args []string, opts options) (*lldbSession, error) {
lldbr, in, err := os.Pipe()
if err != nil {
return nil, err
} }
s := &lldbSession{ sigPath := imgPath + ".signature"
in: in, cmd = idevCmd(exec.Command("ideviceimagemounter", imgPath, sigPath))
out: new(buf), if out, err := cmd.CombinedOutput(); err != nil {
exited: make(chan error), os.Stderr.Write(out)
return fmt.Errorf("ideviceimagemounter: %v", err)
} }
iosdPath, err := exec.LookPath("ios-deploy")
if err != nil {
return nil, err
}
cmdArgs := []string{
// lldb tries to be clever with terminals.
// So we wrap it in script(1) and be clever
// right back at it.
"script",
"-q", "-t", "0",
"/dev/null",
iosdPath,
"--debug",
"-u",
"-r",
"-n",
`--args=` + strings.Join(args, " ") + ``,
"--bundle", appdir,
}
if deviceID != "" {
cmdArgs = append(cmdArgs, "--id", deviceID)
}
s.cmd = exec.Command(cmdArgs[0], cmdArgs[1:]...)
if debug {
log.Println(strings.Join(s.cmd.Args, " "))
}
var out io.Writer = s.out
if opts.lldb {
out = io.MultiWriter(out, os.Stderr)
}
s.cmd.Stdout = out
s.cmd.Stderr = out // everything of interest is on stderr
s.cmd.Stdin = lldbr
if err := s.cmd.Start(); err != nil {
return nil, fmt.Errorf("ios-deploy failed to start: %v", err)
}
// Manage the -test.timeout here, outside of the test. There is a lot
// of moving parts in an iOS test harness (notably lldb) that can
// swallow useful stdio or cause its own ruckus.
if opts.timeout > 1*time.Second {
s.timedout = make(chan struct{})
time.AfterFunc(opts.timeout-1*time.Second, func() {
close(s.timedout)
})
}
go func() {
s.exited <- s.cmd.Wait()
}()
return s, nil
}
func (s *lldbSession) do(cmd string) { s.doCmd(cmd, "(lldb)", 0) }
func (s *lldbSession) doCmd(cmd string, waitFor string, extraTimeout time.Duration) {
startLen := s.out.Len()
fmt.Fprintln(s.in, cmd)
cond := func(out *buf) bool {
i := s.out.LastIndex([]byte(waitFor))
return i > startLen
}
if err := s.wait(fmt.Sprintf("running cmd %q", cmd), cond, extraTimeout); err != nil {
panic(waitPanic{err})
}
}
func (s *lldbSession) wait(reason string, cond func(out *buf) bool, extraTimeout time.Duration) error {
doTimeout := 2*time.Second + extraTimeout
doTimedout := time.After(doTimeout)
for {
select {
case <-s.timedout:
if p := s.cmd.Process; p != nil {
p.Kill()
}
return fmt.Errorf("test timeout (%s)", reason)
case <-doTimedout:
if p := s.cmd.Process; p != nil {
p.Kill()
}
return fmt.Errorf("command timeout (%s for %v)", reason, doTimeout)
case err := <-s.exited:
return fmt.Errorf("exited (%s: %v)", reason, err)
default:
if cond(s.out) {
return nil return nil
}
// findDevImage use the device iOS version and build to locate a suitable
// developer image.
func findDevImage() (string, error) {
cmd := idevCmd(exec.Command("ideviceinfo"))
out, err := cmd.Output()
if err != nil {
return "", fmt.Errorf("ideviceinfo: %v", err)
} }
time.Sleep(20 * time.Millisecond) var iosVer, buildVer string
} lines := bytes.Split(out, []byte("\n"))
} for _, line := range lines {
} spl := bytes.SplitN(line, []byte(": "), 2)
if len(spl) != 2 {
type buf struct {
mu sync.Mutex
buf []byte
}
func (w *buf) Write(in []byte) (n int, err error) {
w.mu.Lock()
defer w.mu.Unlock()
w.buf = append(w.buf, in...)
return len(in), nil
}
func (w *buf) LastIndex(sep []byte) int {
w.mu.Lock()
defer w.mu.Unlock()
return bytes.LastIndex(w.buf, sep)
}
func (w *buf) Bytes() []byte {
w.mu.Lock()
defer w.mu.Unlock()
b := make([]byte, len(w.buf))
copy(b, w.buf)
return b
}
func (w *buf) Len() int {
w.mu.Lock()
defer w.mu.Unlock()
return len(w.buf)
}
type waitPanic struct {
err error
}
type options struct {
timeout time.Duration
lldb bool
}
func parseArgs(binArgs []string) (opts options, remainingArgs []string) {
var flagArgs []string
for _, arg := range binArgs {
if strings.Contains(arg, "-test.timeout") {
flagArgs = append(flagArgs, arg)
}
if strings.Contains(arg, "-lldb") {
flagArgs = append(flagArgs, arg)
continue continue
} }
remainingArgs = append(remainingArgs, arg) key, val := string(spl[0]), string(spl[1])
switch key {
case "ProductVersion":
iosVer = val
case "BuildVersion":
buildVer = val
} }
f := flag.NewFlagSet("", flag.ContinueOnError) }
f.DurationVar(&opts.timeout, "test.timeout", 10*time.Minute, "") if iosVer == "" || buildVer == "" {
f.BoolVar(&opts.lldb, "lldb", false, "") return "", errors.New("failed to parse ideviceinfo output")
f.Parse(flagArgs) }
return opts, remainingArgs verSplit := strings.Split(iosVer, ".")
if len(verSplit) > 2 {
// Developer images are specific to major.minor ios version.
// Cut off the patch version.
iosVer = strings.Join(verSplit[:2], ".")
}
sdkBase := "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport"
patterns := []string{fmt.Sprintf("%s (%s)", iosVer, buildVer), fmt.Sprintf("%s (*)", iosVer), fmt.Sprintf("%s*", iosVer)}
for _, pattern := range patterns {
matches, err := filepath.Glob(filepath.Join(sdkBase, pattern, "DeveloperDiskImage.dmg"))
if err != nil {
return "", fmt.Errorf("findDevImage: %v", err)
}
if len(matches) > 0 {
return matches[0], nil
}
}
return "", fmt.Errorf("failed to find matching developer image for iOS version %s build %s", iosVer, buildVer)
}
// startDebugBridge ensures that the idevicedebugserverproxy runs on
// port 3222.
func startDebugBridge() (func(), error) {
errChan := make(chan error, 1)
cmd := idevCmd(exec.Command("idevicedebugserverproxy", "3222"))
var stderr bytes.Buffer
cmd.Stderr = &stderr
if err := cmd.Start(); err != nil {
return nil, fmt.Errorf("idevicedebugserverproxy: %v", err)
}
go func() {
if err := cmd.Wait(); err != nil {
if _, ok := err.(*exec.ExitError); ok {
errChan <- fmt.Errorf("idevicedebugserverproxy: %s", stderr.Bytes())
} else {
errChan <- fmt.Errorf("idevicedebugserverproxy: %v", err)
}
}
errChan <- nil
}()
closer := func() {
cmd.Process.Kill()
<-errChan
}
// Dial localhost:3222 to ensure the proxy is ready.
delay := time.Second / 4
for attempt := 0; attempt < 5; attempt++ {
conn, err := net.DialTimeout("tcp", "localhost:3222", 5*time.Second)
if err == nil {
conn.Close()
return closer, nil
}
select {
case <-time.After(delay):
delay *= 2
case err := <-errChan:
return nil, err
}
}
closer()
return nil, errors.New("failed to set up idevicedebugserverproxy")
}
// findDeviceAppPath returns the device path to the app with the
// given bundle ID. It parses the output of ideviceinstaller -l -o xml,
// looking for the bundle ID and the corresponding Path value.
func findDeviceAppPath(bundleID string) (string, error) {
cmd := idevCmd(exec.Command("ideviceinstaller", "-l", "-o", "xml"))
out, err := cmd.CombinedOutput()
if err != nil {
os.Stderr.Write(out)
return "", fmt.Errorf("ideviceinstaller: -l -o xml %v", err)
}
var list struct {
Apps []struct {
Data []byte `xml:",innerxml"`
} `xml:"array>dict"`
}
if err := xml.Unmarshal(out, &list); err != nil {
return "", fmt.Errorf("failed to parse ideviceinstaller output: %v", err)
}
for _, app := range list.Apps {
values, err := parsePlistDict(app.Data)
if err != nil {
return "", fmt.Errorf("findDeviceAppPath: failed to parse app dict: %v", err)
}
if values["CFBundleIdentifier"] == bundleID {
if path, ok := values["Path"]; ok {
return path, nil
}
}
}
return "", fmt.Errorf("failed to find device path for bundle: %s", bundleID)
}
// Parse an xml encoded plist. Plist values are mapped to string.
func parsePlistDict(dict []byte) (map[string]string, error) {
d := xml.NewDecoder(bytes.NewReader(dict))
values := make(map[string]string)
var key string
var hasKey bool
for {
tok, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
if tok, ok := tok.(xml.StartElement); ok {
if tok.Name.Local == "key" {
if err := d.DecodeElement(&key, &tok); err != nil {
return nil, err
}
hasKey = true
} else if hasKey {
var val string
var err error
switch n := tok.Name.Local; n {
case "true", "false":
// Bools are represented as <true/> and <false/>.
val = n
err = d.Skip()
default:
err = d.DecodeElement(&val, &tok)
}
if err != nil {
return nil, err
}
values[key] = val
hasKey = false
} else {
if err := d.Skip(); err != nil {
return nil, err
}
}
}
}
return values, nil
}
func uninstall(bundleID string) error {
cmd := idevCmd(exec.Command(
"ideviceinstaller",
"-U", bundleID,
))
if out, err := cmd.CombinedOutput(); err != nil {
os.Stderr.Write(out)
return fmt.Errorf("ideviceinstaller -U %q: %s", bundleID, err)
}
return nil
}
func install(appdir string) error {
attempt := 0
for {
cmd := idevCmd(exec.Command(
"ideviceinstaller",
"-i", appdir,
))
if out, err := cmd.CombinedOutput(); err != nil {
// Sometimes, installing the app fails for some reason.
// Give the device a few seconds and try again.
if attempt < 5 {
time.Sleep(5 * time.Second)
attempt++
continue
}
os.Stderr.Write(out)
return fmt.Errorf("ideviceinstaller -i %q: %v (%d attempts)", appdir, err, attempt)
}
return nil
}
}
func idevCmd(cmd *exec.Cmd) *exec.Cmd {
if deviceID != "" {
// Inject -u device_id after the executable, but before the arguments.
args := []string{cmd.Args[0], "-u", deviceID}
cmd.Args = append(args, cmd.Args[1:]...)
}
return cmd
}
func run(appdir, bundleID string, args []string) error {
var env []string
for _, e := range os.Environ() {
// Don't override TMPDIR on the device.
if strings.HasPrefix(e, "TMPDIR=") {
continue
}
env = append(env, e)
}
attempt := 0
for {
// The device app path reported by the device might be stale, so retry
// the lookup of the device path along with the lldb launching below.
deviceapp, err := findDeviceAppPath(bundleID)
if err != nil {
// The device app path might not yet exist for a newly installed app.
if attempt == 5 {
return err
}
attempt++
time.Sleep(5 * time.Second)
continue
}
lldb := exec.Command(
"python",
"-", // Read script from stdin.
appdir,
deviceapp,
)
lldb.Args = append(lldb.Args, args...)
lldb.Env = env
lldb.Stdin = strings.NewReader(lldbDriver)
lldb.Stdout = os.Stdout
var out bytes.Buffer
lldb.Stderr = io.MultiWriter(&out, os.Stderr)
err = lldb.Start()
if err == nil {
// Forward SIGQUIT to the lldb driver which in turn will forward
// to the running program.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
proc := lldb.Process
go func() {
for sig := range sigs {
proc.Signal(sig)
}
}()
err = lldb.Wait()
signal.Stop(sigs)
close(sigs)
}
// If the program was not started it can be retried without papering over
// real test failures.
started := bytes.HasPrefix(out.Bytes(), []byte("lldb: running program"))
if started || err == nil || attempt == 5 {
return err
}
// Sometimes, the app was not yet ready to launch or the device path was
// stale. Retry.
attempt++
time.Sleep(5 * time.Second)
}
} }
func copyLocalDir(dst, src string) error { func copyLocalDir(dst, src string) error {
@ -656,3 +721,91 @@ const resourceRules = `<?xml version="1.0" encoding="UTF-8"?>
</dict> </dict>
</plist> </plist>
` `
const lldbDriver = `
import sys
import os
import signal
exe, device_exe, args = sys.argv[1], sys.argv[2], sys.argv[3:]
env = []
for k, v in os.environ.items():
env.append(k + "=" + v)
sys.path.append('/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Resources/Python')
import lldb
debugger = lldb.SBDebugger.Create()
debugger.SetAsync(True)
debugger.SkipLLDBInitFiles(True)
err = lldb.SBError()
target = debugger.CreateTarget(exe, None, 'remote-ios', True, err)
if not target.IsValid() or not err.Success():
sys.stderr.write("lldb: failed to setup up target: %s\n" % (err))
sys.exit(1)
target.modules[0].SetPlatformFileSpec(lldb.SBFileSpec(device_exe))
listener = debugger.GetListener()
process = target.ConnectRemote(listener, 'connect://localhost:3222', None, err)
if not err.Success():
sys.stderr.write("lldb: failed to connect to remote target: %s\n" % (err))
sys.exit(1)
# Don't stop on signals.
sigs = process.GetUnixSignals()
for i in range(0, sigs.GetNumSignals()):
sig = sigs.GetSignalAtIndex(i)
sigs.SetShouldStop(sig, False)
sigs.SetShouldNotify(sig, False)
event = lldb.SBEvent()
running = False
prev_handler = None
while True:
if not listener.WaitForEvent(1, event):
continue
if not lldb.SBProcess.EventIsProcessEvent(event):
continue
if running:
# Pass through stdout and stderr.
while True:
out = process.GetSTDOUT(8192)
if not out:
break
sys.stdout.write(out)
while True:
out = process.GetSTDERR(8192)
if not out:
break
sys.stderr.write(out)
state = process.GetStateFromEvent(event)
if state in [lldb.eStateCrashed, lldb.eStateDetached, lldb.eStateUnloaded, lldb.eStateExited]:
if running:
signal.signal(signal.SIGQUIT, prev_handler)
break
elif state == lldb.eStateConnected:
process.RemoteLaunch(args, env, None, None, None, None, 0, False, err)
if not err.Success():
sys.stderr.write("lldb: failed to launch remote process: %s\n" % (err))
process.Kill()
debugger.Terminate()
sys.exit(1)
# Forward SIGQUIT to the program.
def signal_handler(signal, frame):
process.Signal(signal)
prev_handler = signal.signal(signal.SIGQUIT, signal_handler)
# Tell the Go driver that the program is running and should not be retried.
sys.stderr.write("lldb: running program\n")
running = True
# Process stops once at the beginning. Continue.
process.Continue()
exitStatus = process.GetExitStatus()
process.Kill()
debugger.Terminate()
sys.exit(exitStatus)
`

View file

@ -9,7 +9,7 @@
# content languages and encodings, so choose them carefully. # content languages and encodings, so choose them carefully.
# #
# Internet media types should be registered as described in RFC 4288. # Internet media types should be registered as described in RFC 4288.
# The registry is at <http://www.iana.org/assignments/media-types/>. # The registry is at <https://www.iana.org/assignments/media-types/>.
# #
# MIME type (lowercased) Extensions # MIME type (lowercased) Extensions
# ============================================ ========== # ============================================ ==========

View file

@ -1,8 +1,8 @@
This directory contains helper file for trace viewer (`go tool trace`). This directory contains helper file for trace viewer (`go tool trace`).
`trace_viewer_lean.html` was generated by following `trace_viewer_full.html` was generated by following
[instructions](https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md) [instructions](https://github.com/catapult-project/catapult/blob/master/tracing/docs/embedding-trace-viewer.md)
on revision `623a005a3ffa9de13c4b92bc72290e7bcd1ca591` on revision `dc970d3e1f7b3da5a2849de70ff253acdb70148f`
of [catapult](https://github.com/catapult-project/catapult) using: of [catapult](https://github.com/catapult-project/catapult) using:
``` ```
catapult$ ./tracing/bin/vulcanize_trace_viewer --config=full catapult$ ./tracing/bin/vulcanize_trace_viewer --config=full

File diff suppressed because one or more lines are too long

14
misc/wasm/go_js_wasm_exec Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
# Copyright 2018 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
exec node "$DIR/wasm_exec.js" "$@"

30
misc/wasm/wasm_exec.html Normal file
View file

@ -0,0 +1,30 @@
<!doctype html>
<!--
Copyright 2018 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<html>
<head>
<meta charset="utf-8">
<title>Go wasm</title>
</head>
<body>
<script src="wasm_exec.js"></script>
<script>
async function loadAndCompile() {
let resp = await fetch("test.wasm");
let bytes = await resp.arrayBuffer();
await go.compile(bytes);
document.getElementById("runButton").disabled = false;
}
loadAndCompile();
</script>
<button onClick="console.clear(); go.run();" id="runButton" disabled>Run</button>
</body>
</html>

335
misc/wasm/wasm_exec.js Executable file
View file

@ -0,0 +1,335 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
(() => {
let args = ["js"];
// Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
const isNodeJS = typeof process !== "undefined";
if (isNodeJS) {
if (process.argv.length < 3) {
process.stderr.write("usage: go_js_wasm_exec [wasm binary]\n");
process.exit(1);
}
args = args.concat(process.argv.slice(3));
global.require = require;
global.fs = require("fs");
const nodeCrypto = require("crypto");
global.crypto = {
getRandomValues(b) {
nodeCrypto.randomFillSync(b);
},
};
const now = () => {
const [sec, nsec] = process.hrtime();
return sec * 1000 + nsec / 1000000;
};
global.performance = {
timeOrigin: Date.now() - now(),
now: now,
};
const util = require("util");
global.TextEncoder = util.TextEncoder;
global.TextDecoder = util.TextDecoder;
} else {
window.global = window;
global.process = {
env: {},
exit(code) {
if (code !== 0) {
console.warn("exit code:", code);
}
},
};
let outputBuf = "";
global.fs = {
constants: {},
writeSync(fd, buf) {
outputBuf += decoder.decode(buf);
const nl = outputBuf.lastIndexOf("\n");
if (nl != -1) {
console.log(outputBuf.substr(0, nl));
outputBuf = outputBuf.substr(nl + 1);
}
return buf.length;
},
};
}
const encoder = new TextEncoder("utf-8");
const decoder = new TextDecoder("utf-8");
let mod, inst;
let values = []; // TODO: garbage collection
const mem = () => {
// The buffer may change when requesting more memory.
return new DataView(inst.exports.mem.buffer);
}
const setInt64 = (addr, v) => {
mem().setUint32(addr + 0, v, true);
mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
}
const getInt64 = (addr) => {
const low = mem().getUint32(addr + 0, true);
const high = mem().getInt32(addr + 4, true);
return low + high * 4294967296;
}
const loadValue = (addr) => {
const id = mem().getUint32(addr, true);
return values[id];
}
const storeValue = (addr, v) => {
if (v === undefined) {
mem().setUint32(addr, 0, true);
return;
}
if (v === null) {
mem().setUint32(addr, 1, true);
return;
}
values.push(v);
mem().setUint32(addr, values.length - 1, true);
}
const loadSlice = (addr) => {
const array = getInt64(addr + 0);
const len = getInt64(addr + 8);
return new Uint8Array(inst.exports.mem.buffer, array, len);
}
const loadSliceOfValues = (addr) => {
const array = getInt64(addr + 0);
const len = getInt64(addr + 8);
const a = new Array(len);
for (let i = 0; i < len; i++) {
const id = mem().getUint32(array + i * 4, true);
a[i] = values[id];
}
return a;
}
const loadString = (addr) => {
const saddr = getInt64(addr + 0);
const len = getInt64(addr + 8);
return decoder.decode(new DataView(inst.exports.mem.buffer, saddr, len));
}
global.go = {
async compileAndRun(source) {
await go.compile(source);
await go.run();
},
async compile(source) {
mod = await WebAssembly.compile(source);
},
async run() {
let importObject = {
go: {
// func wasmExit(code int32)
"runtime.wasmExit": (sp) => {
process.exit(mem().getInt32(sp + 8, true));
},
// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
"runtime.wasmWrite": (sp) => {
const fd = getInt64(sp + 8);
const p = getInt64(sp + 16);
const n = mem().getInt32(sp + 24, true);
fs.writeSync(fd, new Uint8Array(inst.exports.mem.buffer, p, n));
},
// func nanotime() int64
"runtime.nanotime": (sp) => {
setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000);
},
// func walltime() (sec int64, nsec int32)
"runtime.walltime": (sp) => {
const msec = (new Date).getTime();
setInt64(sp + 8, msec / 1000);
mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
},
// func boolVal(value bool) Value
"syscall/js.boolVal": (sp) => {
storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
},
// func intVal(value int) Value
"syscall/js.intVal": (sp) => {
storeValue(sp + 16, getInt64(sp + 8));
},
// func floatVal(value float64) Value
"syscall/js.floatVal": (sp) => {
storeValue(sp + 16, mem().getFloat64(sp + 8, true));
},
// func stringVal(value string) Value
"syscall/js.stringVal": (sp) => {
storeValue(sp + 24, loadString(sp + 8));
},
// func (v Value) Get(key string) Value
"syscall/js.Value.Get": (sp) => {
storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
},
// func (v Value) set(key string, value Value)
"syscall/js.Value.set": (sp) => {
Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
},
// func (v Value) Index(i int) Value
"syscall/js.Value.Index": (sp) => {
storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
},
// func (v Value) setIndex(i int, value Value)
"syscall/js.Value.setIndex": (sp) => {
Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
},
// func (v Value) call(name string, args []Value) (Value, bool)
"syscall/js.Value.call": (sp) => {
try {
const v = loadValue(sp + 8);
const m = Reflect.get(v, loadString(sp + 16));
const args = loadSliceOfValues(sp + 32);
storeValue(sp + 56, Reflect.apply(m, v, args));
mem().setUint8(sp + 60, 1);
} catch (err) {
storeValue(sp + 56, err);
mem().setUint8(sp + 60, 0);
}
},
// func (v Value) invoke(args []Value) (Value, bool)
"syscall/js.Value.invoke": (sp) => {
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
storeValue(sp + 40, Reflect.apply(v, undefined, args));
mem().setUint8(sp + 44, 1);
} catch (err) {
storeValue(sp + 40, err);
mem().setUint8(sp + 44, 0);
}
},
// func (v Value) new(args []Value) (Value, bool)
"syscall/js.Value.new": (sp) => {
try {
const v = loadValue(sp + 8);
const args = loadSliceOfValues(sp + 16);
storeValue(sp + 40, Reflect.construct(v, args));
mem().setUint8(sp + 44, 1);
} catch (err) {
storeValue(sp + 40, err);
mem().setUint8(sp + 44, 0);
}
},
// func (v Value) Float() float64
"syscall/js.Value.Float": (sp) => {
mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
},
// func (v Value) Int() int
"syscall/js.Value.Int": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8)));
},
// func (v Value) Bool() bool
"syscall/js.Value.Bool": (sp) => {
mem().setUint8(sp + 16, !!loadValue(sp + 8));
},
// func (v Value) Length() int
"syscall/js.Value.Length": (sp) => {
setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
},
// func (v Value) prepareString() (Value, int)
"syscall/js.Value.prepareString": (sp) => {
const str = encoder.encode(String(loadValue(sp + 8)));
storeValue(sp + 16, str);
setInt64(sp + 24, str.length);
},
// func (v Value) loadString(b []byte)
"syscall/js.Value.loadString": (sp) => {
const str = loadValue(sp + 8);
loadSlice(sp + 16).set(str);
},
"debug": (value) => {
console.log(value);
},
}
};
inst = await WebAssembly.instantiate(mod, importObject);
values = [undefined, null, global, inst.exports.mem];
// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
let offset = 4096;
const strPtr = (str) => {
let ptr = offset;
new Uint8Array(inst.exports.mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
offset += str.length + (8 - (str.length % 8));
return ptr;
};
const argc = args.length;
const argvPtrs = [];
args.forEach((arg) => {
argvPtrs.push(strPtr(arg));
});
const keys = Object.keys(process.env).sort();
argvPtrs.push(keys.length);
keys.forEach((key) => {
argvPtrs.push(strPtr(`${key}=${process.env[key]}`));
});
const argv = offset;
argvPtrs.forEach((ptr) => {
mem().setUint32(offset, ptr, true);
mem().setUint32(offset + 4, 0, true);
offset += 8;
});
try {
inst.exports.run(argc, argv);
} catch (err) {
console.error(err);
process.exit(1);
}
}
}
if (isNodeJS) {
go.compileAndRun(fs.readFileSync(process.argv[2])).catch((err) => {
console.error(err);
process.exit(1);
});
}
})();

View file

@ -23,17 +23,10 @@ if [ "$GOOS" != "android" ]; then
exit 1 exit 1
fi fi
if [ -z $GOARM ]; then if [ -n "$GOARM" ] && [ "$GOARM" != "7" ]; then
export GOARM=7
fi
if [ "$GOARM" != "7" ]; then
echo "android only supports GOARM=7, got GOARM=$GOARM" 1>&2 echo "android only supports GOARM=7, got GOARM=$GOARM" 1>&2
exit 1 exit 1
fi fi
if [ "$GOARCH" = "" ]; then
echo "GOARCH must be set" 1>&2
exit 1
fi
export CGO_ENABLED=1 export CGO_ENABLED=1
unset GOBIN unset GOBIN
@ -77,8 +70,8 @@ cp -a "${GOROOT}/lib" "${FAKE_GOROOT}/"
cp -a "${pkgdir}" "${FAKE_GOROOT}/pkg/" cp -a "${pkgdir}" "${FAKE_GOROOT}/pkg/"
echo '# Syncing test files to android device' echo '# Syncing test files to android device'
adb shell mkdir -p /data/local/tmp/goroot adb $GOANDROID_ADB_FLAGS shell mkdir -p /data/local/tmp/goroot
time adb sync data &> /dev/null time adb $GOANDROID_ADB_FLAGS sync data &> /dev/null
export CLEANER=${ANDROID_TEST_DIR}/androidcleaner-$$ export CLEANER=${ANDROID_TEST_DIR}/androidcleaner-$$
cp ../misc/android/cleaner.go $CLEANER.go cp ../misc/android/cleaner.go $CLEANER.go
@ -86,8 +79,8 @@ echo 'var files = `' >> $CLEANER.go
(cd $ANDROID_PRODUCT_OUT/data/local/tmp/goroot; find . >> $CLEANER.go) (cd $ANDROID_PRODUCT_OUT/data/local/tmp/goroot; find . >> $CLEANER.go)
echo '`' >> $CLEANER.go echo '`' >> $CLEANER.go
go build -o $CLEANER $CLEANER.go go build -o $CLEANER $CLEANER.go
adb push $CLEANER /data/local/tmp/cleaner adb $GOANDROID_ADB_FLAGS push $CLEANER /data/local/tmp/cleaner
adb shell /data/local/tmp/cleaner adb $GOANDROID_ADB_FLAGS shell /data/local/tmp/cleaner
echo '' echo ''

View file

@ -56,7 +56,7 @@ func (he headerError) Error() string {
const ( const (
// Type '0' indicates a regular file. // Type '0' indicates a regular file.
TypeReg = '0' TypeReg = '0'
TypeRegA = '\x00' // For legacy support; use TypeReg instead TypeRegA = '\x00' // Deprecated: Use TypeReg instead.
// Type '1' to '6' are header-only flags and may not have a data body. // Type '1' to '6' are header-only flags and may not have a data body.
TypeLink = '1' // Hard link TypeLink = '1' // Hard link
@ -138,7 +138,10 @@ var basicKeys = map[string]bool{
// should do so by creating a new Header and copying the fields // should do so by creating a new Header and copying the fields
// that they are interested in preserving. // that they are interested in preserving.
type Header struct { type Header struct {
Typeflag byte // Type of header entry (should be TypeReg for most files) // Typeflag is the type of header entry.
// The zero value is automatically promoted to either TypeReg or TypeDir
// depending on the presence of a trailing slash in Name.
Typeflag byte
Name string // Name of file entry Name string // Name of file entry
Linkname string // Target name of link (valid for TypeLink or TypeSymlink) Linkname string // Target name of link (valid for TypeLink or TypeSymlink)
@ -184,7 +187,7 @@ type Header struct {
// The key and value should be non-empty UTF-8 strings. // The key and value should be non-empty UTF-8 strings.
// //
// When Writer.WriteHeader is called, PAX records derived from the // When Writer.WriteHeader is called, PAX records derived from the
// the other fields in Header take precedence over PAXRecords. // other fields in Header take precedence over PAXRecords.
PAXRecords map[string]string PAXRecords map[string]string
// Format specifies the format of the tar header. // Format specifies the format of the tar header.

View file

@ -64,7 +64,6 @@ func (tr *Reader) next() (*Header, error) {
// normally be visible to the outside. As such, this loop iterates through // normally be visible to the outside. As such, this loop iterates through
// one or more "header files" until it finds a "normal file". // one or more "header files" until it finds a "normal file".
format := FormatUSTAR | FormatPAX | FormatGNU format := FormatUSTAR | FormatPAX | FormatGNU
loop:
for { for {
// Discard the remainder of the file and any padding. // Discard the remainder of the file and any padding.
if err := discard(tr.r, tr.curr.PhysicalRemaining()); err != nil { if err := discard(tr.r, tr.curr.PhysicalRemaining()); err != nil {
@ -102,7 +101,7 @@ loop:
Format: format, Format: format,
}, nil }, nil
} }
continue loop // This is a meta header affecting the next header continue // This is a meta header affecting the next header
case TypeGNULongName, TypeGNULongLink: case TypeGNULongName, TypeGNULongLink:
format.mayOnlyBe(FormatGNU) format.mayOnlyBe(FormatGNU)
realname, err := ioutil.ReadAll(tr) realname, err := ioutil.ReadAll(tr)
@ -117,7 +116,7 @@ loop:
case TypeGNULongLink: case TypeGNULongLink:
gnuLongLink = p.parseString(realname) gnuLongLink = p.parseString(realname)
} }
continue loop // This is a meta header affecting the next header continue // This is a meta header affecting the next header
default: default:
// The old GNU sparse format is handled here since it is technically // The old GNU sparse format is handled here since it is technically
// just a regular file with additional attributes. // just a regular file with additional attributes.
@ -131,8 +130,12 @@ loop:
if gnuLongLink != "" { if gnuLongLink != "" {
hdr.Linkname = gnuLongLink hdr.Linkname = gnuLongLink
} }
if hdr.Typeflag == TypeRegA && strings.HasSuffix(hdr.Name, "/") { if hdr.Typeflag == TypeRegA {
if strings.HasSuffix(hdr.Name, "/") {
hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories hdr.Typeflag = TypeDir // Legacy archives use trailing slash for directories
} else {
hdr.Typeflag = TypeReg
}
} }
// The extended headers may have updated the size. // The extended headers may have updated the size.
@ -200,7 +203,7 @@ func (tr *Reader) handleSparseFile(hdr *Header, rawHdr *block) error {
// readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers. // readGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers.
// If they are found, then this function reads the sparse map and returns it. // If they are found, then this function reads the sparse map and returns it.
// This assumes that 0.0 headers have already been converted to 0.1 headers // This assumes that 0.0 headers have already been converted to 0.1 headers
// by the the PAX header parsing logic. // by the PAX header parsing logic.
func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) { func (tr *Reader) readGNUSparsePAXHeaders(hdr *Header) (sparseDatas, error) {
// Identify the version of GNU headers. // Identify the version of GNU headers.
var is1x0 bool var is1x0 bool

View file

@ -189,7 +189,7 @@ func TestReader(t *testing.T) {
Gid: 5000, Gid: 5000,
Size: 5, Size: 5,
ModTime: time.Unix(1244593104, 0), ModTime: time.Unix(1244593104, 0),
Typeflag: '\x00', Typeflag: '0',
}, { }, {
Name: "small2.txt", Name: "small2.txt",
Mode: 0444, Mode: 0444,
@ -197,7 +197,7 @@ func TestReader(t *testing.T) {
Gid: 5000, Gid: 5000,
Size: 11, Size: 11,
ModTime: time.Unix(1244593104, 0), ModTime: time.Unix(1244593104, 0),
Typeflag: '\x00', Typeflag: '0',
}}, }},
}, { }, {
file: "testdata/pax.tar", file: "testdata/pax.tar",
@ -537,6 +537,7 @@ func TestReader(t *testing.T) {
Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo", Name: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/foo",
Uid: 010000000, Uid: 010000000,
ModTime: time.Unix(0, 0), ModTime: time.Unix(0, 0),
Typeflag: '0',
}}, }},
}, { }, {
// USTAR archive with a regular entry with non-zero device numbers. // USTAR archive with a regular entry with non-zero device numbers.

View file

@ -306,6 +306,7 @@ func TestRoundTrip(t *testing.T) {
ModTime: time.Now().Round(time.Second), ModTime: time.Now().Round(time.Second),
PAXRecords: map[string]string{"uid": "2097152"}, PAXRecords: map[string]string{"uid": "2097152"},
Format: FormatPAX, Format: FormatPAX,
Typeflag: TypeReg,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
t.Fatalf("tw.WriteHeader: %v", err) t.Fatalf("tw.WriteHeader: %v", err)

Binary file not shown.

Binary file not shown.

View file

@ -5,7 +5,6 @@
package tar package tar
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"path" "path"
@ -71,6 +70,16 @@ func (tw *Writer) WriteHeader(hdr *Header) error {
} }
tw.hdr = *hdr // Shallow copy of Header tw.hdr = *hdr // Shallow copy of Header
// Avoid usage of the legacy TypeRegA flag, and automatically promote
// it to use TypeReg or TypeDir.
if tw.hdr.Typeflag == TypeRegA {
if strings.HasSuffix(tw.hdr.Name, "/") {
tw.hdr.Typeflag = TypeDir
} else {
tw.hdr.Typeflag = TypeReg
}
}
// Round ModTime and ignore AccessTime and ChangeTime unless // Round ModTime and ignore AccessTime and ChangeTime unless
// the format is explicitly chosen. // the format is explicitly chosen.
// This ensures nominal usage of WriteHeader (without specifying the format) // This ensures nominal usage of WriteHeader (without specifying the format)
@ -166,7 +175,7 @@ func (tw *Writer) writePAXHeader(hdr *Header, paxHdrs map[string]string) error {
sort.Strings(keys) sort.Strings(keys)
// Write each record to a buffer. // Write each record to a buffer.
var buf bytes.Buffer var buf strings.Builder
for _, k := range keys { for _, k := range keys {
rec, err := formatPAXRecord(k, paxHdrs[k]) rec, err := formatPAXRecord(k, paxHdrs[k])
if err != nil { if err != nil {

View file

@ -461,6 +461,15 @@ func TestWriter(t *testing.T) {
testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil}, testHeader{Header{Name: strings.Repeat("123456789/", 30)}, nil},
testClose{nil}, testClose{nil},
}, },
}, {
// Automatically promote zero value of Typeflag depending on the name.
file: "testdata/file-and-dir.tar",
tests: []testFnc{
testHeader{Header{Name: "small.txt", Size: 5}, nil},
testWrite{"Kilts", 5, nil},
testHeader{Header{Name: "dir/"}, nil},
testClose{nil},
},
}} }}
equalError := func(x, y error) bool { equalError := func(x, y error) bool {
@ -809,8 +818,8 @@ func TestValidTypeflagWithPAXHeader(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Failed to read header: %s", err) t.Fatalf("Failed to read header: %s", err)
} }
if header.Typeflag != 0 { if header.Typeflag != TypeReg {
t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag) t.Fatalf("Typeflag should've been %d, found %d", TypeReg, header.Typeflag)
} }
} }
} }

View file

@ -366,7 +366,7 @@ parseExtras:
epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC) epoch := time.Date(1601, time.January, 1, 0, 0, 0, 0, time.UTC)
modified = time.Unix(epoch.Unix()+secs, nsecs) modified = time.Unix(epoch.Unix()+secs, nsecs)
} }
case unixExtraID: case unixExtraID, infoZipUnixExtraID:
if len(fieldBuf) < 8 { if len(fieldBuf) < 8 {
continue parseExtras continue parseExtras
} }
@ -379,12 +379,6 @@ parseExtras:
} }
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
modified = time.Unix(ts, 0) modified = time.Unix(ts, 0)
case infoZipUnixExtraID:
if len(fieldBuf) < 4 {
continue parseExtras
}
ts := int64(fieldBuf.uint32()) // ModTime since Unix epoch
modified = time.Unix(ts, 0)
} }
} }

View file

@ -414,7 +414,7 @@ var tests = []ZipTest{
Name: "test.txt", Name: "test.txt",
Content: []byte{}, Content: []byte{},
Size: 1<<32 - 1, Size: 1<<32 - 1,
Modified: time.Date(2017, 10, 31, 21, 17, 27, 0, timeZone(-7*time.Hour)), Modified: time.Date(2017, 10, 31, 21, 11, 57, 0, timeZone(-7*time.Hour)),
Mode: 0644, Mode: 0644,
}, },
}, },

View file

@ -82,7 +82,8 @@ const (
type FileHeader struct { type FileHeader struct {
// Name is the name of the file. // Name is the name of the file.
// It must be a relative path, not start with a drive letter (e.g. C:), // It must be a relative path, not start with a drive letter (e.g. C:),
// and must use forward slashes instead of back slashes. // and must use forward slashes instead of back slashes. A trailing slash
// indicates that this file is a directory and should have no data.
Name string Name string
// Comment is any arbitrary user-defined string shorter than 64KiB. // Comment is any arbitrary user-defined string shorter than 64KiB.

View file

@ -11,6 +11,7 @@ import (
"hash" "hash"
"hash/crc32" "hash/crc32"
"io" "io"
"strings"
"unicode/utf8" "unicode/utf8"
) )
@ -209,7 +210,8 @@ func (w *Writer) Close() error {
// The file contents will be compressed using the Deflate method. // The file contents will be compressed using the Deflate method.
// The name must be a relative path: it must not start with a drive // The name must be a relative path: it must not start with a drive
// letter (e.g. C:) or leading slash, and only forward slashes are // letter (e.g. C:) or leading slash, and only forward slashes are
// allowed. // allowed. To create a directory instead of a file, add a trailing
// slash to the name.
// The file's contents must be written to the io.Writer before the next // The file's contents must be written to the io.Writer before the next
// call to Create, CreateHeader, or Close. // call to Create, CreateHeader, or Close.
func (w *Writer) Create(name string) (io.Writer, error) { func (w *Writer) Create(name string) (io.Writer, error) {
@ -261,8 +263,6 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
return nil, errors.New("archive/zip: invalid duplicate FileHeader") return nil, errors.New("archive/zip: invalid duplicate FileHeader")
} }
fh.Flags |= 0x8 // we will write a data descriptor
// The ZIP format has a sad state of affairs regarding character encoding. // The ZIP format has a sad state of affairs regarding character encoding.
// Officially, the name and comment fields are supposed to be encoded // Officially, the name and comment fields are supposed to be encoded
// in CP-437 (which is mostly compatible with ASCII), unless the UTF-8 // in CP-437 (which is mostly compatible with ASCII), unless the UTF-8
@ -319,7 +319,28 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
fh.Extra = append(fh.Extra, mbuf[:]...) fh.Extra = append(fh.Extra, mbuf[:]...)
} }
fw := &fileWriter{ var (
ow io.Writer
fw *fileWriter
)
h := &header{
FileHeader: fh,
offset: uint64(w.cw.count),
}
if strings.HasSuffix(fh.Name, "/") {
// Set the compression method to Store to ensure data length is truly zero,
// which the writeHeader method always encodes for the size fields.
// This is necessary as most compression formats have non-zero lengths
// even when compressing an empty string.
fh.Method = Store
fh.Flags &^= 0x8 // we will not write a data descriptor
ow = dirWriter{}
} else {
fh.Flags |= 0x8 // we will write a data descriptor
fw = &fileWriter{
zipw: w.cw, zipw: w.cw,
compCount: &countWriter{w: w.cw}, compCount: &countWriter{w: w.cw},
crc32: crc32.NewIEEE(), crc32: crc32.NewIEEE(),
@ -334,20 +355,16 @@ func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
return nil, err return nil, err
} }
fw.rawCount = &countWriter{w: fw.comp} fw.rawCount = &countWriter{w: fw.comp}
fw.header = h
h := &header{ ow = fw
FileHeader: fh,
offset: uint64(w.cw.count),
} }
w.dir = append(w.dir, h) w.dir = append(w.dir, h)
fw.header = h
if err := writeHeader(w.cw, fh); err != nil { if err := writeHeader(w.cw, fh); err != nil {
return nil, err return nil, err
} }
// If we're creating a directory, fw is nil.
w.last = fw w.last = fw
return fw, nil return ow, nil
} }
func writeHeader(w io.Writer, h *FileHeader) error { func writeHeader(w io.Writer, h *FileHeader) error {
@ -400,6 +417,12 @@ func (w *Writer) compressor(method uint16) Compressor {
return comp return comp
} }
type dirWriter struct{}
func (dirWriter) Write([]byte) (int, error) {
return 0, errors.New("zip: write to directory")
}
type fileWriter struct { type fileWriter struct {
*header *header
zipw io.Writer zipw io.Writer

View file

@ -6,6 +6,7 @@ package zip
import ( import (
"bytes" "bytes"
"encoding/binary"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -299,6 +300,52 @@ func TestWriterFlush(t *testing.T) {
} }
} }
func TestWriterDir(t *testing.T) {
w := NewWriter(ioutil.Discard)
dw, err := w.Create("dir/")
if err != nil {
t.Fatal(err)
}
if _, err := dw.Write([]byte("hello")); err == nil {
t.Error("Write to directory: got nil error, want non-nil")
}
}
func TestWriterDirAttributes(t *testing.T) {
var buf bytes.Buffer
w := NewWriter(&buf)
if _, err := w.Create("dir/"); err != nil {
t.Fatal(err)
}
if err := w.Close(); err != nil {
t.Fatal(err)
}
b := buf.Bytes()
var sig [4]byte
binary.LittleEndian.PutUint32(sig[:], uint32(fileHeaderSignature))
idx := bytes.Index(b, sig[:])
if idx == -1 {
t.Fatal("file header not found")
}
b = b[idx:]
if !bytes.Equal(b[6:10], []byte{0, 0, 0, 0}) { // FileHeader.Flags: 0, FileHeader.Method: 0
t.Errorf("unexpected method and flags: %v", b[6:10])
}
if !bytes.Equal(b[14:26], make([]byte, 12)) { // FileHeader.{CRC32,CompressSize,UncompressedSize} all zero.
t.Errorf("unexpected crc, compress and uncompressed size to be 0 was: %v", b[14:26])
}
binary.LittleEndian.PutUint32(sig[:], uint32(dataDescriptorSignature))
if bytes.Index(b, sig[:]) != -1 {
t.Error("there should be no data descriptor")
}
}
func testCreate(t *testing.T, w *Writer, wt *WriteTest) { func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
header := &FileHeader{ header := &FileHeader{
Name: wt.Name, Name: wt.Name,

View file

@ -15,6 +15,7 @@ import (
"internal/testenv" "internal/testenv"
"io" "io"
"io/ioutil" "io/ioutil"
"runtime"
"sort" "sort"
"strings" "strings"
"testing" "testing"
@ -140,14 +141,7 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
rp = &r.buf[len(r.buf)-1] rp = &r.buf[len(r.buf)-1]
// Fast path, if p is entirely the same byte repeated. // Fast path, if p is entirely the same byte repeated.
if lastByte := rp.b; len(p) > 0 && p[0] == lastByte { if lastByte := rp.b; len(p) > 0 && p[0] == lastByte {
all := true if bytes.Count(p, []byte{lastByte}) == len(p) {
for _, b := range p {
if b != lastByte {
all = false
break
}
}
if all {
rp.n += int64(len(p)) rp.n += int64(len(p))
return len(p), nil return len(p), nil
} }
@ -165,6 +159,25 @@ func (r *rleBuffer) Write(p []byte) (n int, err error) {
return len(p), nil return len(p), nil
} }
func min(x, y int) int {
if x < y {
return x
}
return y
}
func memset(a []byte, b byte) {
if len(a) == 0 {
return
}
// Double, until we reach power of 2 >= len(a), same as bytes.Repeat,
// but without allocation.
a[0] = b
for i, l := 1, len(a); i < l; i *= 2 {
copy(a[i:], a[:i])
}
}
func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) { func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
if len(p) == 0 { if len(p) == 0 {
return return
@ -176,16 +189,13 @@ func (r *rleBuffer) ReadAt(p []byte, off int64) (n int, err error) {
parts := r.buf[skipParts:] parts := r.buf[skipParts:]
if len(parts) > 0 { if len(parts) > 0 {
skipBytes := off - parts[0].off skipBytes := off - parts[0].off
for len(parts) > 0 { for _, part := range parts {
part := parts[0] repeat := min(int(part.n-skipBytes), len(p)-n)
for i := skipBytes; i < part.n; i++ { memset(p[n:n+repeat], part.b)
n += repeat
if n == len(p) { if n == len(p) {
return return
} }
p[n] = part.b
n++
}
parts = parts[1:]
skipBytes = 0 skipBytes = 0
} }
} }
@ -452,6 +462,9 @@ func suffixIsZip64(t *testing.T, zip sizedReaderAt) bool {
// Zip64 is required if the total size of the records is uint32max. // Zip64 is required if the total size of the records is uint32max.
func TestZip64LargeDirectory(t *testing.T) { func TestZip64LargeDirectory(t *testing.T) {
if runtime.GOARCH == "wasm" {
t.Skip("too slow on wasm")
}
if testing.Short() { if testing.Short() {
t.Skip("skipping in short mode") t.Skip("skipping in short mode")
} }

View file

@ -77,7 +77,11 @@ else
rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}" rm -rf "pkg/${gohostos}_${gohostarch}" "pkg/tool/${gohostos}_${gohostarch}"
fi fi
GITREV=$(git rev-parse --short HEAD) if [ "$BOOTSTRAP_FORMAT" = "mintgz" ]; then
# Fetch git revision before rm -rf .git.
GITREV=$(git rev-parse --short HEAD)
fi
rm -rf pkg/bootstrap pkg/obj .git rm -rf pkg/bootstrap pkg/obj .git
# Support for building minimal tar.gz for the builders. # Support for building minimal tar.gz for the builders.

View file

@ -462,6 +462,8 @@ func (b *Reader) ReadString(delim byte) (string, error) {
// WriteTo implements io.WriterTo. // WriteTo implements io.WriterTo.
// This may make multiple calls to the Read method of the underlying Reader. // This may make multiple calls to the Read method of the underlying Reader.
// If the underlying reader supports the WriteTo method,
// this calls the underlying WriteTo without buffering.
func (b *Reader) WriteTo(w io.Writer) (n int64, err error) { func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
n, err = b.writeBuf(w) n, err = b.writeBuf(w)
if err != nil { if err != nil {
@ -684,7 +686,9 @@ func (b *Writer) WriteString(s string) (int, error) {
return nn, nil return nn, nil
} }
// ReadFrom implements io.ReaderFrom. // ReadFrom implements io.ReaderFrom. If the underlying writer
// supports the ReadFrom method, and b has no buffered data yet,
// this calls the underlying ReadFrom without buffering.
func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) { func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
if b.Buffered() == 0 { if b.Buffered() == 0 {
if w, ok := b.wr.(io.ReaderFrom); ok { if w, ok := b.wr.(io.ReaderFrom); ok {

View file

@ -7,6 +7,7 @@
package bytes package bytes
import ( import (
"internal/bytealg"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
) )
@ -46,12 +47,16 @@ func explode(s []byte, n int) [][]byte {
return a[0:na] return a[0:na]
} }
// countGeneric actually implements Count // Count counts the number of non-overlapping instances of sep in s.
func countGeneric(s, sep []byte) int { // If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
// special case // special case
if len(sep) == 0 { if len(sep) == 0 {
return utf8.RuneCount(s) + 1 return utf8.RuneCount(s) + 1
} }
if len(sep) == 1 {
return bytealg.Count(s, sep[0])
}
n := 0 n := 0
for { for {
i := Index(s, sep) i := Index(s, sep)
@ -800,9 +805,9 @@ func EqualFold(s, t []byte) bool {
tr, sr = sr, tr tr, sr = sr, tr
} }
// Fast check for ASCII. // Fast check for ASCII.
if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' { if tr < utf8.RuneSelf {
// ASCII, and sr is upper case. tr must be lower case. // ASCII only, sr/tr must be upper/lower case
if tr == sr+'a'-'A' { if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
continue continue
} }
return false return false
@ -824,6 +829,92 @@ func EqualFold(s, t []byte) bool {
return len(s) == len(t) return len(s) == len(t)
} }
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= bytealg.MaxLen:
// Use brute force when s and sep both are small
if len(s) <= bytealg.MaxBruteForce {
return bytealg.Index(s, sep)
}
c := sep[0]
i := 0
t := s[:len(s)-n+1]
fails := 0
for i < len(t) {
if t[i] != c {
// IndexByte is faster than bytealg.Index, so use it as long as
// we're not getting lots of false positives.
o := IndexByte(t[i:], c)
if o < 0 {
return -1
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to bytealg.Index when IndexByte produces too many false positives.
if fails > bytealg.Cutover(i) {
r := bytealg.Index(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
c := sep[0]
i := 0
fails := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < len(t) {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
func indexRabinKarp(s, sep []byte) int { func indexRabinKarp(s, sep []byte) int {
// Rabin-Karp search // Rabin-Karp search
hashsep, pow := hashStr(sep) hashsep, pow := hashStr(sep)

View file

@ -1,88 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bytes
import "internal/cpu"
//go:noescape
// indexShortStr returns the index of the first instance of c in s, or -1 if c is not present in s.
// indexShortStr requires 2 <= len(c) <= shortStringLen
func indexShortStr(s, c []byte) int // ../runtime/asm_amd64.s
func countByte(s []byte, c byte) int // ../runtime/asm_amd64.s
var shortStringLen int
func init() {
if cpu.X86.HasAVX2 {
shortStringLen = 63
} else {
shortStringLen = 31
}
}
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= shortStringLen:
// Use brute force when s and sep both are small
if len(s) <= 64 {
return indexShortStr(s, sep)
}
c := sep[0]
i := 0
t := s[:len(s)-n+1]
fails := 0
for i < len(t) {
if t[i] != c {
// IndexByte skips 16/32 bytes per iteration,
// so it's faster than indexShortStr.
o := IndexByte(t[i:], c)
if o < 0 {
return -1
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to indexShortStr when IndexByte produces too many false positives.
// Too many means more that 1 error per 8 characters.
// Allow some errors in the beginning.
if fails > (i+16)/8 {
r := indexShortStr(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
return indexRabinKarp(s, sep)
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
if len(sep) == 1 && cpu.X86.HasPOPCNT {
return countByte(s, sep[0])
}
return countGeneric(s, sep)
}

View file

@ -1,68 +0,0 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bytes
func countByte(s []byte, c byte) int // bytes_arm64.s
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
}
c := sep[0]
i := 0
fails := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < len(t) {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
if len(sep) == 1 {
return countByte(s, sep[0])
}
return countGeneric(s, sep)
}

View file

@ -6,19 +6,19 @@ package bytes
//go:noescape //go:noescape
// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s. // IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
func IndexByte(s []byte, c byte) int // ../runtime/asm_$GOARCH.s func IndexByte(b []byte, c byte) int // in internal/bytealg
//go:noescape //go:noescape
// Equal returns a boolean reporting whether a and b // Equal returns a boolean reporting whether a and b
// are the same length and contain the same bytes. // are the same length and contain the same bytes.
// A nil argument is equivalent to an empty slice. // A nil argument is equivalent to an empty slice.
func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s func Equal(a, b []byte) bool // in internal/bytealg
//go:noescape //go:noescape
// Compare returns an integer comparing two byte slices lexicographically. // Compare returns an integer comparing two byte slices lexicographically.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b. // The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
// A nil argument is equivalent to an empty slice. // A nil argument is equivalent to an empty slice.
func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s func Compare(a, b []byte) int // in internal/bytealg

View file

@ -1,65 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !amd64,!s390x,!arm64
package bytes
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
}
c := sep[0]
i := 0
fails := 0
t := s[:len(s)-n+1]
for i < len(t) {
if t[i] != c {
o := IndexByte(t[i:], c)
if o < 0 {
break
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
i++
fails++
if fails >= 4+i>>4 && i < len(t) {
// Give up on IndexByte, it isn't skipping ahead
// far enough to be better than Rabin-Karp.
// Experiments (using IndexPeriodic) suggest
// the cutover is about 16 byte skips.
// TODO: if large prefixes of sep are matching
// we should cutover at even larger average skips,
// because Equal becomes that much more expensive.
// This code does not take that effect into account.
j := indexRabinKarp(s[i:], sep)
if j < 0 {
return -1
}
return i + j
}
}
return -1
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
return countGeneric(s, sep)
}

View file

@ -1,86 +0,0 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package bytes
//go:noescape
// indexShortStr returns the index of the first instance of sep in s,
// or -1 if sep is not present in s.
// indexShortStr requires 2 <= len(sep) <= shortStringLen
func indexShortStr(s, c []byte) int // ../runtime/asm_s390x.s
// supportsVX reports whether the vector facility is available.
// indexShortStr must not be called if the vector facility is not
// available.
func supportsVX() bool // ../runtime/asm_s390x.s
var shortStringLen = -1
func init() {
if supportsVX() {
shortStringLen = 64
}
}
// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
func Index(s, sep []byte) int {
n := len(sep)
switch {
case n == 0:
return 0
case n == 1:
return IndexByte(s, sep[0])
case n == len(s):
if Equal(sep, s) {
return 0
}
return -1
case n > len(s):
return -1
case n <= shortStringLen:
// Use brute force when s and sep both are small
if len(s) <= 64 {
return indexShortStr(s, sep)
}
c := sep[0]
i := 0
t := s[:len(s)-n+1]
fails := 0
for i < len(t) {
if t[i] != c {
// IndexByte skips 16/32 bytes per iteration,
// so it's faster than indexShortStr.
o := IndexByte(t[i:], c)
if o < 0 {
return -1
}
i += o
}
if Equal(s[i:i+n], sep) {
return i
}
fails++
i++
// Switch to indexShortStr when IndexByte produces too many false positives.
// Too many means more that 1 error per 8 characters.
// Allow some errors in the beginning.
if fails > (i+16)/8 {
r := indexShortStr(s[i:], sep)
if r >= 0 {
return r + i
}
return -1
}
}
return -1
}
return indexRabinKarp(s, sep)
}
// Count counts the number of non-overlapping instances of sep in s.
// If sep is an empty slice, Count returns 1 + the number of UTF-8-encoded code points in s.
func Count(s, sep []byte) int {
return countGeneric(s, sep)
}

View file

@ -410,10 +410,6 @@ func TestCountByte(t *testing.T) {
if p != j+1 { if p != j+1 {
t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p) t.Errorf("TestCountByte.Count(%q, 100) = %d", b[i:i+window], p)
} }
pGeneric := CountGeneric(b[i:i+window], []byte{100})
if pGeneric != j+1 {
t.Errorf("TestCountByte.CountGeneric(%q, 100) = %d", b[i:i+window], p)
}
} }
} }
@ -461,10 +457,6 @@ func TestCountByteNoMatch(t *testing.T) {
if p != 0 { if p != 0 {
t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p) t.Errorf("TestCountByteNoMatch(%q, 0) = %d", b[i:i+window], p)
} }
pGeneric := CountGeneric(b[i:i+window], []byte{0})
if pGeneric != 0 {
t.Errorf("TestCountByteNoMatch.CountGeneric(%q, 100) = %d", b[i:i+window], p)
}
for j := 0; j < window; j++ { for j := 0; j < window; j++ {
b[i+j] = byte(0) b[i+j] = byte(0)
} }

View file

@ -7,4 +7,3 @@ package bytes
// Export func for testing // Export func for testing
var IndexBytePortable = indexBytePortable var IndexBytePortable = indexBytePortable
var EqualPortable = equalPortable var EqualPortable = equalPortable
var CountGeneric = countGeneric

Some files were not shown because too many files have changed in this diff Show more